<!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>NoSql</title>
        <style>
</style>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.10.2/dist/katex.min.css" integrity="sha384-yFRtMMDnQtDRO8rLpMIKrtPCD5jdktao2TV19YiZYWMDkUR5GQZR/NOVTdquEx1j" crossorigin="anonymous">
<link href="https://cdn.jsdelivr.net/npm/katex-copytex@latest/dist/katex-copytex.min.css" rel="stylesheet" type="text/css">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Microsoft/vscode/extensions/markdown-language-features/media/markdown.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Microsoft/vscode/extensions/markdown-language-features/media/highlight.css">
<style>
            body {
                font-family: -apple-system, BlinkMacSystemFont, 'Segoe WPC', 'Segoe UI', system-ui, 'Ubuntu', 'Droid Sans', sans-serif;
                font-size: 14px;
                line-height: 1.6;
            }
        </style>
        <style>
.task-list-item { list-style-type: none; } .task-list-item-checkbox { margin-left: -20px; vertical-align: middle; }
</style>
        
        <script src="https://cdn.jsdelivr.net/npm/katex-copytex@latest/dist/katex-copytex.min.js"></script>
        
    </head>
    <body class="vscode-light">
        <ul>
<li><a href="#nosql">NoSql</a>
<ul>
<li><a href="#%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E7%94%A8nosql">为什么要用Nosql</a></li>
<li><a href="#nosql%E7%9A%84%E7%89%B9%E7%82%B9">NoSQL的特点</a></li>
<li><a href="#nosql%E7%9A%84%E5%9B%9B%E5%A4%A7%E5%88%86%E7%B1%BB">NoSql的四大分类</a></li>
</ul>
</li>
<li><a href="#redis">Redis</a>
<ul>
<li><a href="#redis%E6%A6%82%E8%BF%B0">Redis概述</a></li>
<li><a href="#redis-%E7%9A%84%E7%89%B9%E7%82%B9">Redis 的特点</a></li>
<li><a href="#redis%E4%B8%8E%E5%85%B6%E4%BB%96key-value%E5%AD%98%E5%82%A8%E6%9C%89%E4%BB%80%E4%B9%88%E4%B8%8D%E5%90%8C">Redis与其他key-value存储有什么不同？</a></li>
<li><a href="#redis%E5%AE%89%E8%A3%85%E5%92%8C%E4%BD%BF%E7%94%A8">Redis安装和使用</a></li>
<li><a href="#%E6%B5%8B%E8%AF%95%E5%B9%B6%E5%8F%91%E8%BF%9E%E6%8E%A5%E4%B8%8A%E7%BD%91%E6%9F%A5%E9%85%8D%E7%BD%AE">测试并发连接（上网查配置）</a></li>
<li><a href="#redis%E5%85%A5%E9%97%A8">redis入门</a></li>
<li><a href="#redis%E6%98%AF%E5%8D%95%E7%BA%BF%E7%A8%8B">redis是单线程</a></li>
<li><a href="#%E4%B8%BA%E4%BB%80%E4%B9%88%E5%8D%95%E7%BA%BF%E7%A8%8B%E5%9F%BA%E4%BA%8E%E9%82%A3%E4%B9%88%E5%BF%AB">为什么单线程基于那么快</a></li>
<li><a href="#%E5%B8%B8%E8%A7%81%E7%9A%84%E4%BA%94%E5%A4%A7%E7%B1%BB%E5%9E%8B">常见的五大类型</a>
<ul>
<li><a href="#string%E7%B1%BB%E5%9E%8B%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%B1%BB%E5%9E%8B">String类型，字符串类型</a></li>
<li><a href="#list%E5%88%97%E8%A1%A8">List（列表）</a></li>
<li><a href="#set%E9%9B%86%E5%90%88">Set（集合）</a></li>
<li><a href="#hash%E5%93%88%E5%B8%8C-map%E9%9B%86%E5%90%88-key-map--key-key-value">Hash（哈希， Map集合， key-map ===&gt;  key-(key-value)）</a></li>
<li><a href="#zset%E6%9C%89%E5%BA%8F%E9%9B%86%E5%90%88%E5%9C%A8set%E7%9A%84%E9%9B%86%E5%90%88%E4%B8%8A%E5%A2%9E%E5%8A%A0%E4%BA%86%E4%B8%80%E4%B8%AA%E5%80%BC-%E6%88%90%E7%BB%A9%E6%8E%92%E5%BA%8F%E5%B7%A5%E8%B5%84%E6%8E%92%E5%BA%8F%E6%99%AE%E9%80%9A%E6%B6%88%E6%81%AF%E5%92%8C%E9%87%8D%E8%A6%81%E6%B6%88%E6%81%AFtop-n">ZSet（有序集合，在set的集合上增加了一个值， 成绩排序，工资排序，普通消息和重要消息，Top N）</a></li>
<li><a href="#%E4%B8%89%E7%A7%8D%E7%89%B9%E6%AE%8A%E7%B1%BB%E5%9E%8B">三种特殊类型</a>
<ul>
<li><a href="#geospatial%E5%9C%B0%E7%90%86%E4%BD%8D%E7%BD%AE%E4%B8%A4%E6%9E%81%E6%97%A0%E6%B3%95%E6%B7%BB%E5%8A%A0%E6%9C%8B%E5%8F%8B%E5%AE%9A%E4%BD%8D-%E6%89%93%E8%BD%A6%E8%B7%9D%E7%A6%BB%E8%AE%A1%E7%AE%97">geospatial地理位置（两极无法添加，朋友定位， 打车距离计算）</a></li>
</ul>
</li>
<li><a href="#hyperloglogv289%E6%8E%A5%E5%8F%97081%E7%9A%84%E8%AF%AF%E5%B7%AE%E7%BB%9F%E8%AE%A1%E7%94%A8%E6%88%B7%E8%AE%BF%E9%97%AE%E9%87%8F-%E5%90%88%E5%B9%B6%E6%95%B0%E6%8D%AE%E9%9B%86">Hyperloglog（v2.8.9，接受0.81%的误差，统计用户访问量， 合并数据集）</a></li>
<li><a href="#bitmaps%E6%B4%BB%E8%B7%83%E4%B8%8D%E6%B4%BB%E8%B7%83-%E7%99%BB%E5%BD%95%E6%9C%AA%E7%99%BB%E5%BD%95%E6%89%93%E5%8D%A1">Bitmaps（活跃不活跃， 登录未登录，打卡）</a></li>
</ul>
</li>
<li><a href="#%E4%BA%8B%E5%8A%A1">事务</a>
<ul>
<li><a href="#%E4%B9%90%E8%A7%82%E9%94%81%E6%9B%B4%E6%96%B0%E6%95%B0%E6%8D%AE%E7%9A%84%E6%97%B6%E5%80%99%E5%88%A4%E6%96%AD%E5%88%A4%E6%96%AD%E8%AF%A5%E6%95%B0%E6%8D%AE%E6%98%AF%E5%90%A6%E8%A2%AB%E4%BF%AE%E6%94%B9%E8%8E%B7%E5%8F%96version%E6%9B%B4%E6%96%B0%E7%9A%84%E6%97%B6%E5%80%99%E6%AF%94%E8%BE%83version">乐观锁：更新数据的时候判断，判断该数据是否被修改。获取version，更新的时候比较version</a></li>
<li><a href="#%E6%82%B2%E8%A7%82%E9%94%81-%E6%97%A0%E8%AE%BA%E5%81%9A%E4%BB%80%E4%B9%88%E9%83%BD%E5%8A%A0%E9%94%81">悲观锁: 无论做什么都加锁！</a></li>
</ul>
</li>
<li><a href="#jedis%E4%BD%BF%E7%94%A8java%E6%93%8D%E4%BD%9Credis%E4%BD%BF%E7%94%A8java%E6%93%8D%E4%BD%9Credis%E4%B8%AD%E9%97%B4%E4%BB%B6">Jedis（使用java操作Redis，使用java操作redis中间件）</a></li>
<li><a href="#springboot%E6%95%B4%E5%90%88">SpringBoot整合</a>
<ul>
<li><a href="#%E4%BD%BF%E7%94%A8">使用</a></li>
<li><a href="#%E8%A7%A3%E5%86%B3%E4%B8%8D%E8%83%BD%E5%AD%98%E5%85%A5%E4%B8%AD%E6%96%87">解决不能存入中文</a></li>
<li><a href="#%E4%B8%8D%E8%83%BD%E5%AD%98%E5%85%A5%E5%AF%B9%E8%B1%A1">不能存入对象</a></li>
<li><a href="#spring-boot%E5%B7%A5%E5%85%B7%E5%8C%85">spring boot工具包</a></li>
</ul>
</li>
<li><a href="#redis%E7%9A%84%E6%8C%81%E4%B9%85%E5%8C%96"><strong>redis的持久化</strong></a></li>
<li><a href="#%E5%8F%91%E5%B8%83%E8%AE%A2%E9%98%85%E6%A1%88%E4%BE%8B">发布订阅（案例）</a></li>
<li><a href="#%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6">主从复制</a>
<ul>
<li><a href="#%E6%8E%A8%E8%8D%90%E4%BF%AE%E6%94%B9%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6">推荐修改配置文件</a></li>
<li><a href="#%E5%93%A8%E5%85%B5%E6%A8%A1%E5%BC%8F%E9%9A%8F%E6%9C%BA%E9%80%89%E8%80%81%E5%A4%A7-%E4%B8%BB%E6%9C%BA%E5%9B%9E%E6%9D%A5%E4%BA%86%E5%B0%B1%E6%98%AF%E5%B0%8F%E5%BC%9F%E6%9F%A5%E7%9C%8B%E5%93%A8%E5%85%B5%E7%9A%84%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E5%BC%80%E4%B8%AA%E6%96%B0%E8%BF%9B%E7%A8%8B%E5%93%A8%E5%85%B5%E6%9C%80%E5%A5%BD%E4%B9%9F%E9%85%8D%E5%87%A0%E4%B8%AA">哨兵模式(随机选老大, 主机回来了就是小弟)，查看哨兵的配置文件，开个新进程，哨兵最好也配几个</a></li>
</ul>
</li>
<li><a href="#%E8%87%AA%E5%90%AF%E5%8A%A8">自启动：</a></li>
<li><a href="#config%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6">config配置文件</a></li>
</ul>
</li>
</ul>
<h1 id="nosql">NoSql</h1>
<h2 id="为什么要用nosql">为什么要用Nosql</h2>
<p>有些数据没有固定的结构</p>
<h2 id="nosql的特点">NoSQL的特点</h2>
<ol>
<li>方便扩展</li>
<li>大数据量高性能（NoSQL的缓存记录级，是一种细粒度的缓存，性能比较高）</li>
<li>数据类型是多样型的（不需要事先设计数据库！随取随用）</li>
</ol>
<h2 id="nosql的四大分类">NoSql的四大分类</h2>
<ol>
<li>KV键值对</li>
<li>文档型数据库（bson格式和json一样）<strong>MongoDB</strong>（必学）</li>
<li>列存储数据库 <strong>HBase</strong>，<strong>分布式文件系统</strong></li>
<li>图关系型数据库 朋友圈社交网络等 <strong>Neo4j</strong></li>
</ol>
<h1 id="redis">Redis</h1>
<h2 id="redis概述">Redis概述</h2>
<ol>
<li>Redis 内存中的数据结构存储系统，它可以用作数据库、缓存和消息中间件。</li>
<li>Redis 写8万/s，读11万/s</li>
<li>NoSQL = Not Only SQL（不仅仅是数据库）</li>
<li>是一个高性能的 key-value 数据库（不止key-value类型）</li>
<li>Redis:Remote Dictionary Server(远程字典服务器)</li>
<li>它可以用作<strong>数据库</strong>， <strong>缓存</strong>，<strong>消息中间件</strong></li>
</ol>
<h2 id="redis-的特点">Redis 的特点</h2>
<ol>
<li>Redis支持数据的持久化，可以将数据保存在硬盘中，重启的时候可以再次加载进行使用。</li>
<li>Redis支持多种数据类型，不仅仅支持key-value，同时提供list,set,zset,hash等数据结构的存储。</li>
<li>Redis支持数据备份，即master-slave模式的数据备份</li>
</ol>
<blockquote>
<p>什么是master-slave模式？
<detail>
<summary>答案</summary></p>
</blockquote>
<p>主从设备模式，分而治之的思想,将一个原始任务分解为若干个语义等同的子任务,并由专门的工作者线程来并行执行这些任务,<strong>原始任务的结果是通过整合各个子任务的处理结果形成的.</strong>
</detail></p>
<h2 id="redis与其他key-value存储有什么不同">Redis与其他key-value存储有什么不同？</h2>
<ol>
<li>Redis有着更为复杂的数据结构并且提供对它们的原子性操作。且数据类型都是基于基本数据类型的同时对程序员透明，无需进行额外的抽象。</li>
<li>Redis运行在内存中但是可以持久化到硬盘，所以需要权衡内存（数据量不能大于硬件内存）。Redis 持久化到磁盘中是以追加的方式产生的，因为它不需要随机访问。</li>
</ol>
<h2 id="redis安装和使用">Redis安装和使用</h2>
<ol>
<li>window版：<a href="https://github.com/tporadowski/redis/releases">https://github.com/tporadowski/redis/releases</a></li>
<li>Linu版：官网提供了源码，使用gcc v7编译，make MALLOC=libc</li>
<li>redis-server.exe redis.windows.conf(可以省略，省略后启用默认的)</li>
<li>redis-cli.exe -h 127.0.0.1 -p 6379</li>
<li>设置键值对：set myKey adb</li>
<li>取出键值对： get myKey</li>
</ol>
<p>解压redis，得到源码，可以看到redis.conf</p>
<blockquote>
<p>make
make install
make 后默认安装路径在usr/local/bin
<strong>使用后台启动，redis.config中daemonize 改为yes</strong>
通过指定的配置文件启动：redis-server 配置文件
关闭客户端：shutdown unsave|save
查看是否运行： ps -ef|grep redis
更新gcc yum install centos-release-scl devtoolset-7
使用新的gcc工具链：scl enable devtoolset-7 bash</p>
</blockquote>
<p>安装 Developer Toolset 7 使用 gcc 7 编译</p>
<p>centos: yum install gcc-c++</p>
<pre><code class="language-bash"><div>[root@bogon redis-4.0.6]<span class="hljs-comment"># make distclean      </span>
<span class="hljs-comment"># 清空上次编译失败残留文件</span>

[root@bogon redis-4.0.6]<span class="hljs-comment"># make &amp;&amp; make install    </span>
<span class="hljs-comment">#执行编译及安装</span>
</div></code></pre>
<p>yum install centos-release-scl devtoolset-7<br>
Bash<br>
这不会更新系统原有 gcc 软件包，在当您需要使用 gcc 7 工具链时，使用下列命令进入环境</p>
<p>scl enable devtoolset-7 bash
Bash
安装
wget <a href="https://github.com/antirez/redis/archive/6.0.1.tar.gz">https://github.com/antirez/redis/archive/6.0.1.tar.gz</a>
tar -xvzf 6.0.1.tar.gz
cd redis-6.0.1
./configure
make
make install</p>
<h2 id="测试并发连接上网查配置">测试并发连接（上网查配置）</h2>
<ol>
<li>使用redis-benchmark -h localhost -p 6379 -c 100（多少个并发客户端） -n 100000（并发）</li>
<li>信息：
<ul>
<li>多少个并发完成的时间</li>
<li>几台服务器</li>
<li>每次请求的字节数</li>
<li>多少个并发客户端</li>
</ul>
</li>
</ol>
<h2 id="redis入门">redis入门</h2>
<ol>
<li>默认有16个数据库，查看redis.conf，默认使用的是第0个，使用select切换。select 索引</li>
<li>redis提供了api： jredis</li>
<li>查看数据库大小，DBSIZE</li>
<li>get name查看key的value</li>
<li>keys * 查看数据库中所有的key</li>
<li>清空当前数据库：flushdb</li>
<li>清空全部数据库：flushall</li>
<li>查看是否存在，存在为1，否则为0: exists key名</li>
<li>移除key： move key名 数据库索引</li>
<li>设置过期时间： expire key名 多少秒，使用ttl key名看还有多少秒过期，应用在单点登录</li>
<li>查看key的类型，使用type key名</li>
<li>ping命令，返回pong代表连接成功</li>
<li>设置值 set key 值</li>
<li>clear清屏</li>
</ol>
<h2 id="redis是单线程">redis是单线程</h2>
<p>redis是很快的，redis是基于内存操作，CPU不是Redis性能瓶颈，Redis的瓶颈是机器内存和网络带宽。</p>
<h2 id="为什么单线程基于那么快">为什么单线程基于那么快</h2>
<blockquote>
<p>多线程不一定比单线程快
redis将数据全部放在内存中，所以使用 单线程去操作效率最高，使用多线程后CPU上下文会会切换</p>
</blockquote>
<h2 id="常见的五大类型">常见的五大类型</h2>
<h3 id="string类型字符串类型">String类型，字符串类型</h3>
<ol>
<li>set key名 value # 设置值</li>
<li>为某个key的字符串追加， append key名 字符串</li>
<li>strlen 字符串的长度</li>
<li>incr命令加1，播放量，浏览量</li>
<li>decr自动减1</li>
<li>加对应的步长 incrby key 步长</li>
<li>减对应的步长 decrby key 步长</li>
<li>截取字符串 getRange key startIndex（起始位置） endIndex（结束位置），得到全部字符串：getRange key 0 -1</li>
<li>字符串替换，替换指定字符串的位置的字符串：setRange key 偏移量 字符串</li>
<li>当前值存在setex，set key 过期时间 value 。如果存在设置过期时间</li>
<li>如果不存在setnx， 如果不存在再设置，如果存在不设置。如果设置了返回1，否则返回0。</li>
<li>批量设置 mset key1 value1 key2 value2 key3 value3</li>
<li>批量得到 mget key1 key2 key3</li>
<li>不存在设置，msetnx k1 v1 k2 v2(原子性操作，要么一起成功，要么一起失败)</li>
<li>(<strong>重点</strong>)使用结合json使用，例如：set user:1{name: zhangsan, age: 3}，得到时：get user:1:name， 巧妙的可以直接使用<strong>user:id:name</strong></li>
<li>getset命令：先得到，再set，如果不存在值则返回nil，可以做更新的操作。</li>
</ol>
<h3 id="list列表">List（列表）</h3>
<p>在redis里面，我们可以把list完成，栈，队列，所有的list命令都是以l开头</p>
<ol>
<li>LPUSH List名 值，将一个值或多个值填入<strong>头部（小标为0）</strong>，返回下表</li>
<li>LRange List名 起始坐标 结束坐标， LRange List 0 -1 表示得到全部.</li>
<li>RPush list名 值， 尾部插入</li>
<li>Lpop list 左边移除</li>
<li>Rpop list 右边移除</li>
<li>Lindex list名 下标，通过list获取list中的某个值</li>
<li>Llen list名 返回list列表的长度</li>
<li>移除对应的值！Lrem list名 移除数量 移除的值</li>
<li>移除一部分值，Ltrim list名 开始 结束位置， 截断指定长度</li>
<li>rpoplpush source（源list） destination（目标list） 移除列表最后一个元素，添加最后一个元素到目标list中。</li>
<li>exists 判断是否存在list</li>
<li>lset list名 下标 值， 注意必须要有该list，且下标存在</li>
<li>linsert list before|after 源字符串 值，将某个具体的值插入到列表中某个<strong>元素</strong>的前面或者后面</li>
</ol>
<blockquote>
<p>小结：</p>
</blockquote>
<ul>
<li>list是一个链表</li>
<li>key（list）不存在创建新的链表</li>
<li>如果key存在插入新新增元素</li>
<li>如果移除所有值，空链表</li>
<li>在两边插入或改动值，效率最高！中间元素相对来说效率更低</li>
<li>list可以做成栈和队列</li>
</ul>
<h3 id="set集合">Set（集合）</h3>
<p>redis里面，Set的操作，都是s开头。</p>
<ol>
<li>sadd set名 值 添加元素</li>
<li>smemebers set名 查看</li>
<li>sismember set名 值，查看value是否在set中</li>
<li>scard set名 获取set集合中的内容个数</li>
<li>srem set名 值 移除某个值</li>
<li>srandmember set名，随机得到元素（用途：抽奖）</li>
<li>spop set名 随机删除</li>
<li>smove source destination 移动的成员 将一个集合移动到另一个集合</li>
<li>差集 sdiff set1 set2 保留set1与set2不同的值，set1中的值</li>
<li>并集 sunion set1 set2 合并两个集合</li>
<li>交集 sinter set1 set2 保留相同的</li>
</ol>
<blockquote>
<p>引用场景， 共同关注</p>
</blockquote>
<h3 id="hash哈希-map集合-key-map--key-key-value">Hash（哈希， Map集合， key-map ===&gt;  key-(key-value)）</h3>
<p>都是以h开头，和字符串类似</p>
<ol>
<li>hset hash名 标签 值，存值</li>
<li>hget hash名 标签， 取值</li>
<li>hmset hash名 key1 value1 key2 value2，设置多个值</li>
<li>hmget hash名 标签1 标签2， 得到多个值</li>
<li>hgetall hash名 得到hash中的所有值</li>
<li>hdel hash名 标签 删除指定标签</li>
<li>hexists hash名 标签 判断指定字段是否存在</li>
<li>hkeys hash名 获取所有的字段</li>
<li>hvals hash名 获取所有的值</li>
<li>Hincrby hash名 字段 步长，注意去掉by的</li>
<li>hdecrby hash名 字段 步长</li>
<li>hsetnx hash名 字段 值，如果不存在</li>
<li>剩下的是和string一样</li>
</ol>
<blockquote>
<p>hash用于用户信息的保存，hash更适合存储对象</p>
</blockquote>
<h3 id="zset有序集合在set的集合上增加了一个值-成绩排序工资排序普通消息和重要消息top-n">ZSet（有序集合，在set的集合上增加了一个值， 成绩排序，工资排序，普通消息和重要消息，Top N）</h3>
<ol>
<li>增加值：zadd zset名 序号 值</li>
<li>添加多个值： zadd zset名 序号1 值1 序号2 值2</li>
<li>排序： ZrangeByScore zset名 -inf +inf，最小值到最大值排序，zrangebyscore zset名 -inf +inf withscores，显示小于250的排序：zrangebyScore zset名 -inf 250， 其中inf代表无穷。</li>
<li>移除元素， zrem zset名 字段</li>
<li>zcard zset名， 获取有序集合中的个数</li>
<li>zrevrange zset名 0 -1 从大到小排序</li>
<li>zcount zset名 min max， 获取min到max之间的有序集合数量。</li>
</ol>
<h3 id="三种特殊类型">三种特殊类型</h3>
<h4 id="geospatial地理位置两极无法添加朋友定位-打车距离计算">geospatial地理位置（两极无法添加，朋友定位， 打车距离计算）</h4>
<ol>
<li>geoadd key 纬度 经度 名称，例如：geoadd china:city 维度 经度 shanghai</li>
<li>geodist key 名称1 名称2 单位（km、m、mi、ft）</li>
<li>geohash key 名称1 名称2， 返回一个或多个位置元素将二维的坐标生成11位的hash字符串</li>
<li>geopos key 名称1 名称2 获取指定名称的经纬度</li>
<li>georadius key 维度 经度 半径 半径单位 [withcoord] [count 查询个数] [withdist]，以给定经纬度为中心，找出某个半径的的东西, withcoord带经纬度打印， withdist带距中心的距离， count 查询指定个数。</li>
<li>georadiusbymember key 名称 半径 半径单位， 指定名称下的其他元素</li>
<li>geo的底层就是zset，可以使用zset的元素操作geo，例如：zrange key 0 -1, zrem key 名称：移除</li>
</ol>
<h3 id="hyperloglogv289接受081的误差统计用户访问量-合并数据集">Hyperloglog（v2.8.9，接受0.81%的误差，统计用户访问量， 合并数据集）</h3>
<blockquote>
<p>基数：不重复的元素</p>
</blockquote>
<ol>
<li>pfadd key a b c ……</li>
<li>pfcount key 统计个数</li>
<li>pfmerge key1 key2：合并两个数据集</li>
</ol>
<blockquote>
<p>接受容错才行</p>
</blockquote>
<h3 id="bitmaps活跃不活跃-登录未登录打卡">Bitmaps（活跃不活跃， 登录未登录，打卡）</h3>
<blockquote>
<p>位存储，使用0 1，Bitmaps位图，数据结构！都是</p>
</blockquote>
<ol>
<li>setbit key offset value，设置值</li>
<li>查看某一天是否有打卡： getbit key offset</li>
<li>统计为1的操作：bitcount key start end</li>
</ol>
<p><strong>其余api看，看官方文档</strong></p>
<h2 id="事务">事务</h2>
<blockquote>
<p>事务的本质： 一组命令的集合！一个事务中的所有命令都需要被序列化，在事务执行过程中，会按照顺序执行！
一次性、顺序性、排他性！执行一些命令！
<strong>redis单条命令是保证原子性的，但是事务不保证原子性！</strong>
redis事务没有隔离级别的概念！
所有的命令在事务中，并没还有被执行！只有发起执行命令的时候才执行。</p>
</blockquote>
<blockquote>
<p>redis的事务：</p>
</blockquote>
<ol>
<li>开启事务（multi）</li>
<li>命令入队（一堆命令）</li>
<li>执行事务（exec）</li>
<li>放弃事务(discard)</li>
<li>存在代码问题（<strong>命令错了</strong>），事务中的命令都不会执行！存在语法错误是可以运行的，错了抛异常。</li>
</ol>
<blockquote>
<p>监控：</p>
</blockquote>
<h3 id="乐观锁更新数据的时候判断判断该数据是否被修改获取version更新的时候比较version">乐观锁：更新数据的时候判断，判断该数据是否被修改。获取version，更新的时候比较version</h3>
<ol>
<li>使用watch key 当作乐观锁</li>
<li>执行之前另外一个线程修改了key，这个时候会导致事务执行失败。</li>
<li>使用 unwatch放弃监视， 如果发现事务执行失败，解锁，重新加锁</li>
</ol>
<h3 id="悲观锁-无论做什么都加锁">悲观锁: 无论做什么都加锁！</h3>
<h2 id="jedis使用java操作redis使用java操作redis中间件">Jedis（使用java操作Redis，使用java操作redis中间件）</h2>
<ol>
<li>导入jedis的包，使用fastjson</li>
<li>编码测试：
<ul>
<li>连接redis，new Jedis对象，构造方法的重载</li>
<li>redis的命令对应jedis的方法</li>
<li>关闭连接close()</li>
</ul>
</li>
</ol>
<h2 id="springboot整合">SpringBoot整合</h2>
<blockquote>
<p>SpringBoot所有的配置类，都有一个自动配置类
自动配置类会绑定一个properties配置文件，查找org.spring.springframework.boot下的autoconfigure下METE-INF&gt;spring.factories(自动配置类)，查看对应的配置使用。</p>
<p>简介：</p>
</blockquote>
<ol>
<li>SpringBoot操作数据：spring-data （jpa jdbc mongodb redis等）</li>
<li>SpringData是和SpringBoot齐名的产品</li>
<li>spring2.x 之后，使用jedis被替换为lettuce</li>
</ol>
<blockquote>
<p>jedis和lettuce</p>
</blockquote>
<ol>
<li>jedis采用直连，多线程操作，容易出现线程安全，如果想避免不安全，使用jedis pool连接池！</li>
<li>lettuce底层使用netty，实力可以再多线程中进行共享，不存在线程安全的情况！可以减少数据了。</li>
</ol>
<blockquote>
<p>要连接redis的注意事项：</p>
</blockquote>
<ol>
<li>redis.conf 要配置保护模式</li>
<li>注释掉bind 127.0.0.1</li>
</ol>
<h3 id="使用">使用</h3>
<ol>
<li>注入RedisTemplate</li>
<li>使用redisTemplate对象调用对应的api，opsFor + 命令 = 函数</li>
<li>也可以使用redisTemplate操作事务</li>
<li>操作数据库的连接，调用getConnectionFactoru().getConnection()， 例如flushDB(), flushAll()；一般不使用。</li>
</ol>
<h3 id="解决不能存入中文">解决不能存入中文</h3>
<p>编写配置类，使用@Configuration注解，在RedisAutoConfiguration中粘贴出
redisTemplate模板，返回String类型</p>
<h3 id="不能存入对象">不能存入对象</h3>
<ul>
<li>方法1. 直接序列化</li>
<li>方法2. 编写配置类，然后使用@Configuration注解，编写redisTemplate，在RedisAutoConfiguration中粘贴出redisTemplate模板，返回String类型，在方法中使用template使用设置序列化。注意，需要使用无参构造函数，否则会报：cannot deserialize from Object value (no delegate- or property-based Creator)</li>
</ul>
<pre><code class="language-propertity"><code><div># Redis数据库索引（默认为0）
spring.redis.database=0
# Redis服务器地址
spring.redis.host=127.0.0.1
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码（默认为空）
spring.redis.password=
# 连接池最大连接数（使用负值表示没有限制）
spring.redis.jedis.pool.max-active=20
# 连接池最大阻塞等待时间（使用负值表示没有限制）
spring.redis.jedis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=10
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
# 连接超时时间（毫秒）
spring.redis.timeout=1000
</div></code></code></pre>
<pre><code class="language-java"><div>
<span class="hljs-meta">@Configuration</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">RedisConfig</span> </span>{
    <span class="hljs-meta">@Bean</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> RedisTemplate&lt;String, Object&gt; <span class="hljs-title">redisTemplate</span><span class="hljs-params">(RedisConnectionFactory redisConnectionFactory)</span> </span>{
        RedisTemplate&lt;String, Object&gt; template = <span class="hljs-keyword">new</span> RedisTemplate&lt;&gt;();
        template.setConnectionFactory(redisConnectionFactory);
        <span class="hljs-comment">//String 序列化</span>
        StringRedisSerializer stringRedisSerializer = <span class="hljs-keyword">new</span> StringRedisSerializer();
        template.setKeySerializer(stringRedisSerializer);
        template.setHashKeySerializer(stringRedisSerializer);
        <span class="hljs-comment">// json 序列化</span>
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = <span class="hljs-keyword">new</span> Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = <span class="hljs-keyword">new</span> ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        <span class="hljs-keyword">return</span> template;
    }
}
</div></code></pre>
<h3 id="spring-boot工具包">spring boot工具包</h3>
<pre><code class="language-java"><div><span class="hljs-keyword">import</span> java.util.List;
<span class="hljs-keyword">import</span> java.util.Map;
<span class="hljs-keyword">import</span> java.util.Set;
<span class="hljs-keyword">import</span> java.util.concurrent.TimeUnit;
<span class="hljs-keyword">import</span> org.springframework.beans.factory.annotation.Autowired;
<span class="hljs-keyword">import</span> org.springframework.data.redis.core.RedisTemplate;
<span class="hljs-keyword">import</span> org.springframework.stereotype.Component;
<span class="hljs-keyword">import</span> org.springframework.util.CollectionUtils;
<span class="hljs-comment">/**
 * Redis工具类
 * <span class="hljs-doctag">@author</span> zz
 * <span class="hljs-doctag">@date</span>   2020年6月24日
 */</span>
<span class="hljs-meta">@Component</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">final</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">RedisUtil</span> </span>{
    <span class="hljs-meta">@Autowired</span>
    <span class="hljs-keyword">private</span> RedisTemplate&lt;String, Object&gt; redisTemplate;

    <span class="hljs-comment">/**
     * 指定缓存失效时间
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@param</span> time 时间(秒)
     * <span class="hljs-doctag">@return</span>
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">expire</span><span class="hljs-params">(String key, <span class="hljs-keyword">long</span> time)</span> </span>{
        <span class="hljs-keyword">try</span> {
            <span class="hljs-keyword">if</span> (time &gt; <span class="hljs-number">0</span>) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
        } <span class="hljs-keyword">catch</span> (Exception e) {
            e.printStackTrace();
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
        }
    }

    <span class="hljs-comment">/**
     * 根据key 获取过期时间
     * <span class="hljs-doctag">@param</span> key 键 不能为null
     * <span class="hljs-doctag">@return</span> 时间(秒) 返回0代表为永久有效
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">long</span> <span class="hljs-title">getExpire</span><span class="hljs-params">(String key)</span> </span>{
        <span class="hljs-keyword">return</span> redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }

    <span class="hljs-comment">/**
     * 判断key是否存在
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@return</span> true 存在 false不存在
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">hasKey</span><span class="hljs-params">(String key)</span> </span>{
        <span class="hljs-keyword">try</span> {
            <span class="hljs-keyword">return</span> redisTemplate.hasKey(key);
        } <span class="hljs-keyword">catch</span> (Exception e) {
            e.printStackTrace();
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
        }
    }

    <span class="hljs-comment">/**
     * 删除缓存
     * <span class="hljs-doctag">@param</span> key 可以传一个值 或多个
     */</span>
    <span class="hljs-meta">@SuppressWarnings</span>(<span class="hljs-string">"unchecked"</span>)
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">del</span><span class="hljs-params">(String... key)</span> </span>{
        <span class="hljs-keyword">if</span> (key != <span class="hljs-keyword">null</span> &amp;&amp; key.length &gt; <span class="hljs-number">0</span>) {
            <span class="hljs-keyword">if</span> (key.length == <span class="hljs-number">1</span>) {
                redisTemplate.delete(key[<span class="hljs-number">0</span>]);
            } <span class="hljs-keyword">else</span> {
                redisTemplate.delete(CollectionUtils.arrayToList(key));
            }
        }
    }

    <span class="hljs-comment">/**
     * 普通缓存获取
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@return</span> 值
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> Object <span class="hljs-title">get</span><span class="hljs-params">(String key)</span> </span>{
        <span class="hljs-keyword">return</span> key == <span class="hljs-keyword">null</span> ? <span class="hljs-keyword">null</span> : redisTemplate.opsForValue().get(key);
    }

    <span class="hljs-comment">/**
     * 普通缓存放入
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@param</span> value 值
     * <span class="hljs-doctag">@return</span> true成功 false失败
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">set</span><span class="hljs-params">(String key, Object value)</span> </span>{
        <span class="hljs-keyword">try</span> {
            redisTemplate.opsForValue().set(key, value);
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
        } <span class="hljs-keyword">catch</span> (Exception e) {
            e.printStackTrace();
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
        }
    }

    <span class="hljs-comment">/**
     * 普通缓存放入并设置时间
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@param</span> value 值
     * <span class="hljs-doctag">@param</span> time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
     * <span class="hljs-doctag">@return</span> true成功 false 失败
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">set</span><span class="hljs-params">(String key, Object value, <span class="hljs-keyword">long</span> time)</span> </span>{
        <span class="hljs-keyword">try</span> {
            <span class="hljs-keyword">if</span> (time &gt; <span class="hljs-number">0</span>) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } <span class="hljs-keyword">else</span> {
                set(key, value);
            }
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
        } <span class="hljs-keyword">catch</span> (Exception e) {
            e.printStackTrace();
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
        }
    }
    <span class="hljs-comment">/**
     * 递增
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@param</span> delta 要增加几(大于0)
     * <span class="hljs-doctag">@return</span>
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">long</span> <span class="hljs-title">incr</span><span class="hljs-params">(String key, <span class="hljs-keyword">long</span> delta)</span> </span>{
        <span class="hljs-keyword">if</span> (delta &lt; <span class="hljs-number">0</span>) {
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> RuntimeException(<span class="hljs-string">"递增因子必须大于0"</span>);
        }
        <span class="hljs-keyword">return</span> redisTemplate.opsForValue().increment(key, delta);
    }

    <span class="hljs-comment">/**
     * 递减
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@param</span> delta 要减少几(小于0)
     * <span class="hljs-doctag">@return</span>
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">long</span> <span class="hljs-title">decr</span><span class="hljs-params">(String key, <span class="hljs-keyword">long</span> delta)</span> </span>{
        <span class="hljs-keyword">if</span> (delta &lt; <span class="hljs-number">0</span>) {
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> RuntimeException(<span class="hljs-string">"递减因子必须大于0"</span>);
        }
        <span class="hljs-keyword">return</span> redisTemplate.opsForValue().increment(key, -delta);
    }

    <span class="hljs-comment">/**
     * HashGet
     * <span class="hljs-doctag">@param</span> key 键 不能为null
     * <span class="hljs-doctag">@param</span> item 项 不能为null
     * <span class="hljs-doctag">@return</span> 值
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> Object <span class="hljs-title">hget</span><span class="hljs-params">(String key, String item)</span> </span>{
        <span class="hljs-keyword">return</span> redisTemplate.opsForHash().get(key, item);
    }

    <span class="hljs-comment">/**
     * 获取hashKey对应的所有键值
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@return</span> 对应的多个键值
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> Map&lt;Object, Object&gt; <span class="hljs-title">hmget</span><span class="hljs-params">(String key)</span> </span>{
        <span class="hljs-keyword">return</span> redisTemplate.opsForHash().entries(key);
    }

    <span class="hljs-comment">/**
     * HashSet
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@param</span> map 对应多个键值
     * <span class="hljs-doctag">@return</span> true 成功 false 失败
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">hmset</span><span class="hljs-params">(String key, Map&lt;String, Object&gt; map)</span> </span>{
        <span class="hljs-keyword">try</span> {
            redisTemplate.opsForHash().putAll(key, map);
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
        } <span class="hljs-keyword">catch</span> (Exception e) {
            e.printStackTrace();
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
        }
    }

    <span class="hljs-comment">/**
     * HashSet 并设置时间
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@param</span> map 对应多个键值
     * <span class="hljs-doctag">@param</span> time 时间(秒)
     * <span class="hljs-doctag">@return</span> true成功 false失败
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">hmset</span><span class="hljs-params">(String key, Map&lt;String, Object&gt; map, <span class="hljs-keyword">long</span> time)</span> </span>{
        <span class="hljs-keyword">try</span> {
            redisTemplate.opsForHash().putAll(key, map);
            <span class="hljs-keyword">if</span> (time &gt; <span class="hljs-number">0</span>) {
                expire(key, time);
            }
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
        } <span class="hljs-keyword">catch</span> (Exception e) {
            e.printStackTrace();
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
        }
    }

    <span class="hljs-comment">/**
     * 向一张hash表中放入数据,如果不存在将创建
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@param</span> item 项
     * <span class="hljs-doctag">@param</span> value 值
     * <span class="hljs-doctag">@return</span> true 成功 false失败
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">hset</span><span class="hljs-params">(String key, String item, Object value)</span> </span>{
        <span class="hljs-keyword">try</span> {
            redisTemplate.opsForHash().put(key, item, value);
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
        } <span class="hljs-keyword">catch</span> (Exception e) {
            e.printStackTrace();
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
        }
    }

    <span class="hljs-comment">/**
     * 向一张hash表中放入数据,如果不存在将创建
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@param</span> item 项
     * <span class="hljs-doctag">@param</span> value 值
     * <span class="hljs-doctag">@param</span> time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
     * <span class="hljs-doctag">@return</span> true 成功 false失败
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">hset</span><span class="hljs-params">(String key, String item, Object value, <span class="hljs-keyword">long</span> time)</span> </span>{
        <span class="hljs-keyword">try</span> {
            redisTemplate.opsForHash().put(key, item, value);
            <span class="hljs-keyword">if</span> (time &gt; <span class="hljs-number">0</span>) {
                expire(key, time);
            }
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
        } <span class="hljs-keyword">catch</span> (Exception e) {
            e.printStackTrace();
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
        }
    }

    <span class="hljs-comment">/**
     * 删除hash表中的值
     * <span class="hljs-doctag">@param</span> key 键 不能为null
     * <span class="hljs-doctag">@param</span> item 项 可以使多个 不能为null
     */</span>

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">hdel</span><span class="hljs-params">(String key, Object... item)</span> </span>{
        redisTemplate.opsForHash().delete(key, item);
    }

    <span class="hljs-comment">/**
     * 判断hash表中是否有该项的值
     * <span class="hljs-doctag">@param</span> key 键 不能为null
     * <span class="hljs-doctag">@param</span> item 项 不能为null
     * <span class="hljs-doctag">@return</span> true 存在 false不存在
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">hHasKey</span><span class="hljs-params">(String key, String item)</span> </span>{
        <span class="hljs-keyword">return</span> redisTemplate.opsForHash().hasKey(key, item);
    }

    <span class="hljs-comment">/**
     * hash递增 如果不存在,就会创建一个 并把新增后的值返回
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@param</span> item 项
     * <span class="hljs-doctag">@param</span> by 要增加几(大于0)
     * <span class="hljs-doctag">@return</span>
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> <span class="hljs-title">hincr</span><span class="hljs-params">(String key, String item, <span class="hljs-keyword">double</span> by)</span> </span>{
        <span class="hljs-keyword">return</span> redisTemplate.opsForHash().increment(key, item, by);
    }

    <span class="hljs-comment">/**
     * hash递减
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@param</span> item 项
     * <span class="hljs-doctag">@param</span> by 要减少记(小于0)
     * <span class="hljs-doctag">@return</span>
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> <span class="hljs-title">hdecr</span><span class="hljs-params">(String key, String item, <span class="hljs-keyword">double</span> by)</span> </span>{
        <span class="hljs-keyword">return</span> redisTemplate.opsForHash().increment(key, item, -by);
    }

    <span class="hljs-comment">/**
     * 根据key获取Set中的所有值
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@return</span>
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> Set&lt;Object&gt; <span class="hljs-title">sGet</span><span class="hljs-params">(String key)</span> </span>{
        <span class="hljs-keyword">try</span> {
            <span class="hljs-keyword">return</span> redisTemplate.opsForSet().members(key);
        } <span class="hljs-keyword">catch</span> (Exception e) {
            e.printStackTrace();
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">null</span>;
        }
    }

    <span class="hljs-comment">/**
     * 根据value从一个set中查询,是否存在
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@param</span> value 值
     * <span class="hljs-doctag">@return</span> true 存在 false不存在
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">sHasKey</span><span class="hljs-params">(String key, Object value)</span> </span>{
        <span class="hljs-keyword">try</span> {
            <span class="hljs-keyword">return</span> redisTemplate.opsForSet().isMember(key, value);
        } <span class="hljs-keyword">catch</span> (Exception e) {
            e.printStackTrace();
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
        }
    }

    <span class="hljs-comment">/**
     * 将数据放入set缓存
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@param</span> values 值 可以是多个
     * <span class="hljs-doctag">@return</span> 成功个数
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">long</span> <span class="hljs-title">sSet</span><span class="hljs-params">(String key, Object... values)</span> </span>{
        <span class="hljs-keyword">try</span> {
            <span class="hljs-keyword">return</span> redisTemplate.opsForSet().add(key, values);
        } <span class="hljs-keyword">catch</span> (Exception e) {
            e.printStackTrace();
            <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
        }
    }

    <span class="hljs-comment">/**
     * 将set数据放入缓存
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@param</span> time 时间(秒)
     * <span class="hljs-doctag">@param</span> values 值 可以是多个
     * <span class="hljs-doctag">@return</span> 成功个数
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">long</span> <span class="hljs-title">sSetAndTime</span><span class="hljs-params">(String key, <span class="hljs-keyword">long</span> time, Object... values)</span> </span>{
        <span class="hljs-keyword">try</span> {
            Long count = redisTemplate.opsForSet().add(key, values);
            <span class="hljs-keyword">if</span> (time &gt; <span class="hljs-number">0</span>) {
                expire(key, time);
            }
            <span class="hljs-keyword">return</span> count;
        } <span class="hljs-keyword">catch</span> (Exception e) {
            e.printStackTrace();
            <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
        }
    }

    <span class="hljs-comment">/**
     * 获取set缓存的长度
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@return</span>
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">long</span> <span class="hljs-title">sGetSetSize</span><span class="hljs-params">(String key)</span> </span>{
        <span class="hljs-keyword">try</span> {
            <span class="hljs-keyword">return</span> redisTemplate.opsForSet().size(key);
        } <span class="hljs-keyword">catch</span> (Exception e) {
            e.printStackTrace();
            <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
        }
    }

    <span class="hljs-comment">/**
     * 移除值为value的
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@param</span> values 值 可以是多个
     * <span class="hljs-doctag">@return</span> 移除的个数
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">long</span> <span class="hljs-title">setRemove</span><span class="hljs-params">(String key, Object... values)</span> </span>{
        <span class="hljs-keyword">try</span> {
            Long count = redisTemplate.opsForSet().remove(key, values);
            <span class="hljs-keyword">return</span> count;
        } <span class="hljs-keyword">catch</span> (Exception e) {
            e.printStackTrace();
            <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
        }
    }

    <span class="hljs-comment">/**
     * 获取list缓存的内容
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@param</span> start 开始
     * <span class="hljs-doctag">@param</span> end 结束 0 到 -1代表所有值
     * <span class="hljs-doctag">@return</span>
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> List&lt;Object&gt; <span class="hljs-title">lGet</span><span class="hljs-params">(String key, <span class="hljs-keyword">long</span> start, <span class="hljs-keyword">long</span> end)</span> </span>{
        <span class="hljs-keyword">try</span> {
            <span class="hljs-keyword">return</span> redisTemplate.opsForList().range(key, start, end);
        } <span class="hljs-keyword">catch</span> (Exception e) {
            e.printStackTrace();
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">null</span>;
        }
    }

    <span class="hljs-comment">/**
     * 获取list缓存的长度
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@return</span>
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">long</span> <span class="hljs-title">lGetListSize</span><span class="hljs-params">(String key)</span> </span>{
        <span class="hljs-keyword">try</span> {
            <span class="hljs-keyword">return</span> redisTemplate.opsForList().size(key);
        } <span class="hljs-keyword">catch</span> (Exception e) {
            e.printStackTrace();
            <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
        }
    }

    <span class="hljs-comment">/**
     * 通过索引 获取list中的值
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@param</span> index 索引 index&gt;=0时， 0 表头，1 第二个元素，依次类推；index&lt;0时，-1，表尾，-2倒数第二个元素，依次类推
     * <span class="hljs-doctag">@return</span>
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> Object <span class="hljs-title">lGetIndex</span><span class="hljs-params">(String key, <span class="hljs-keyword">long</span> index)</span> </span>{
        <span class="hljs-keyword">try</span> {
            <span class="hljs-keyword">return</span> redisTemplate.opsForList().index(key, index);
        } <span class="hljs-keyword">catch</span> (Exception e) {
            e.printStackTrace();
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">null</span>;
        }
    }

    <span class="hljs-comment">/**
     * 将list放入缓存
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@param</span> value 值
     * <span class="hljs-doctag">@return</span>
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">lSet</span><span class="hljs-params">(String key, Object value)</span> </span>{
        <span class="hljs-keyword">try</span> {
            redisTemplate.opsForList().rightPush(key, value);
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
        } <span class="hljs-keyword">catch</span> (Exception e) {
            e.printStackTrace();
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
        }
    }

    <span class="hljs-comment">/**
     * 将list放入缓存
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@param</span> value 值
     * <span class="hljs-doctag">@param</span> time 时间(秒)
     * <span class="hljs-doctag">@return</span>
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">lSet</span><span class="hljs-params">(String key, Object value, <span class="hljs-keyword">long</span> time)</span> </span>{
        <span class="hljs-keyword">try</span> {
            redisTemplate.opsForList().rightPush(key, value);
            <span class="hljs-keyword">if</span> (time &gt; <span class="hljs-number">0</span>) {
                expire(key, time);
            }
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
        } <span class="hljs-keyword">catch</span> (Exception e) {
            e.printStackTrace();
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
        }
    }

    <span class="hljs-comment">/**
     * 将list放入缓存
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@param</span> value 值
     * <span class="hljs-doctag">@return</span>
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">lSet</span><span class="hljs-params">(String key, List&lt;Object&gt; value)</span> </span>{
        <span class="hljs-keyword">try</span> {
            redisTemplate.opsForList().rightPushAll(key, value);
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
        } <span class="hljs-keyword">catch</span> (Exception e) {
            e.printStackTrace();
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
        }
    }

    <span class="hljs-comment">/**
     * 将list放入缓存
     *
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@param</span> value 值
     * <span class="hljs-doctag">@param</span> time 时间(秒)
     * <span class="hljs-doctag">@return</span>
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">lSet</span><span class="hljs-params">(String key, List&lt;Object&gt; value, <span class="hljs-keyword">long</span> time)</span> </span>{
        <span class="hljs-keyword">try</span> {
            redisTemplate.opsForList().rightPushAll(key, value);
            <span class="hljs-keyword">if</span> (time &gt; <span class="hljs-number">0</span>) {
                expire(key, time);
            }
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
        } <span class="hljs-keyword">catch</span> (Exception e) {
            e.printStackTrace();
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
        }
    }

    <span class="hljs-comment">/**
     * 根据索引修改list中的某条数据
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@param</span> index 索引
     * <span class="hljs-doctag">@param</span> value 值
     * <span class="hljs-doctag">@return</span>
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">lUpdateIndex</span><span class="hljs-params">(String key, <span class="hljs-keyword">long</span> index, Object value)</span> </span>{
        <span class="hljs-keyword">try</span> {

            redisTemplate.opsForList().set(key, index, value);
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
        } <span class="hljs-keyword">catch</span> (Exception e) {
            e.printStackTrace();
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
        }
    }

    <span class="hljs-comment">/**
     * 移除N个值为value
     * <span class="hljs-doctag">@param</span> key 键
     * <span class="hljs-doctag">@param</span> count 移除多少个
     * <span class="hljs-doctag">@param</span> value 值
     * <span class="hljs-doctag">@return</span> 移除的个数
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">long</span> <span class="hljs-title">lRemove</span><span class="hljs-params">(String key, <span class="hljs-keyword">long</span> count, Object value)</span> </span>{
        <span class="hljs-keyword">try</span> {
            Long remove = redisTemplate.opsForList().remove(key, count, value);
            <span class="hljs-keyword">return</span> remove;
        } <span class="hljs-keyword">catch</span> (Exception e) {
            e.printStackTrace();
            <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
        }
    }
}

</div></code></pre>
<h2 id="redis的持久化"><strong>redis的持久化</strong></h2>
<ol>
<li>rdb，默认方式，dump.rdb，如何使用，只需要把他放到启动目录下，对数据要求不高。
<ul>
<li>save条件满足</li>
<li>flushxxx</li>
<li>退出redis</li>
</ul>
</li>
<li>aof (append only file),将所有的命令记录下来，以日志的形式将所有命令记录下来。默认不开启，配置文件中开启。appendonly yes开启。如果aof文件破坏了，可以使用<code>redis-check-aof</code> 修复。性能稍微有点低，默认每秒同步， aof远远大于rdb</li>
</ol>
<h2 id="发布订阅案例">发布订阅（案例）</h2>
<ol>
<li>消息发布者 publish channel message</li>
<li>消息接收者 subscribe channel</li>
</ol>
<h2 id="主从复制">主从复制</h2>
<ol>
<li>配置对应的机器</li>
<li>在要配置的主机中输入，slaveof ip 端口，该机器就变成从机</li>
</ol>
<h3 id="推荐修改配置文件">推荐修改配置文件</h3>
<ol>
<li>配置<strong>replicaof</strong></li>
<li>有密码配置密码</li>
</ol>
<blockquote>
<p>从机不能写, 主机只能写，主机断掉，还是能用只能读，从机启动后会同步数据。
设置回主节点： slaveof no one</p>
</blockquote>
<h3 id="哨兵模式随机选老大-主机回来了就是小弟查看哨兵的配置文件开个新进程哨兵最好也配几个">哨兵模式(随机选老大, 主机回来了就是小弟)，查看哨兵的配置文件，开个新进程，哨兵最好也配几个</h3>
<ol>
<li>配置哨兵配置文件 sentinel monitor 被监控的名称 host port</li>
<li>启动哨兵 redis-sentinel  配置文件</li>
</ol>
<h2 id="自启动">自启动：</h2>
<pre><code class="language-shell"><div><span class="hljs-meta">#</span><span class="bash">!/bin/bash</span>
<span class="hljs-meta">#</span><span class="bash"> chkconfig: 2345 10 90  </span>
<span class="hljs-meta">#</span><span class="bash"> description: Start and Stop redis  </span>

PATH=/sbin:/usr/bin:/bin 
REDISPORT=6379                           
EXEC=/usr/local/bin/redis-server        
REDIS_CLI=/usr/local/bin/redis-cli     
PIDFILE=/var/run/redis_6379.pid             
CONF="/redis/config/redis.conf"       

case "$1" in   
        start)   
                if [ -f $PIDFILE ]   
                then   
                        echo "$PIDFILE exists, process is already running or crashed."  
                else  
                        echo "Starting Redis server..."  
                        $EXEC $CONF   
                fi   
                if [ "$?"="0" ]   
                then   
                        echo "Redis is running..."  
                fi   
                ;;   
        stop)   
                if [ ! -f $PIDFILE ]   
                then   
                        echo "$PIDFILE exists, process is not running."  
                else  
                        PID=$(cat $PIDFILE)   
                        echo "Stopping..."  
                        if [ x"$2" = x ] 
                        then 
                                $REDIS_CLI -p $REDISPORT  SHUTDOWN    
                                sleep 2  
                                while [ -x $PIDFILE ]   
                                do  
                                        echo "Waiting for Redis to shutdown..."  
                                        sleep 1  
                                done   
                                echo "Redis stopped"  
                        else
                                if [ x"$3" = x ]
                                then
                                        $REDIS_CLI -p $2  SHUTDOWN    
                                        sleep 2  
                                        while [ -x $PIDFILE ]   
                                        do  
                                                echo "Waiting for Redis to shutdown..."  
                                                sleep 1  
                                        done   
                                        echo "Redis stopped" 
                                else
                                        $REDIS_CLI -p $2 -a $3 SHUTDOWN    
                                        sleep 2  
                                        while [ -x $PIDFILE ]   
                                        do  
                                                echo "Waiting for Redis to shutdown..."  
                                                sleep 1  
                                        done   
                                        echo "Redis stopped" 
                                fi

                        fi
                       
                fi   
                ;;   
        restart|force-reload)   
                ${0} stop   
                ${0} start   
                ;;   
        *)   
               echo "Usage: /etc/init.d/redis {start|stop|restart|force-reload}" &gt;&amp;2  
                exit 1  
esac
</div></code></pre>
<p>我们一般在脚本开头加入下面两句就好了</p>
<p># chkconfig:  2345 90 10</p>
<p># description:  myservice</p>
<p>上面的注释的意思是，redis服务必须在运行级2，3，4，5下被启动或关闭，启动的优先级是90，关闭的优先级是10。</p>
<p>90是启动优先级，10是停止优先级，优先级范围是0－100，数字越大，优先级越低。</p>
<p>chmod 775 /etc/init.d/redis</p>
<p>设置自启动：</p>
<p>chkconfig redis on</p>
<p>如果不行的话systemctl start redis</p>
<h2 id="config配置文件">config配置文件</h2>
<ol>
<li>单位,对大小写不敏感</li>
</ol>
<pre><code class="language-bash"><div><span class="hljs-comment"># Redis configuration file example.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># Note that in order to read the configuration file, Redis must be</span>
<span class="hljs-comment"># started with the file path as first argument:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># ./redis-server /path/to/redis.conf</span>

<span class="hljs-comment"># Note on units: when memory size is needed, it is possible to specify</span>
<span class="hljs-comment"># it in the usual form of 1k 5GB 4M and so forth:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># 1k =&gt; 1000 bytes</span>
<span class="hljs-comment"># 1kb =&gt; 1024 bytes</span>
<span class="hljs-comment"># 1m =&gt; 1000000 bytes</span>
<span class="hljs-comment"># 1mb =&gt; 1024*1024 bytes</span>
<span class="hljs-comment"># 1g =&gt; 1000000000 bytes</span>
<span class="hljs-comment"># 1gb =&gt; 1024*1024*1024 bytes</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># units are case insensitive so 1GB 1Gb 1gB are all the same.</span>
</div></code></pre>
<ol start="2">
<li>包含，包含其他配置文件</li>
</ol>
<pre><code class="language-bash"><div><span class="hljs-comment">################################## INCLUDES ###################################</span>

<span class="hljs-comment"># Include one or more other config files here.  This is useful if you</span>
<span class="hljs-comment"># have a standard template that goes to all Redis servers but also need</span>
<span class="hljs-comment"># to customize a few per-server settings.  Include files can include</span>
<span class="hljs-comment"># other files, so use this wisely.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># Notice option "include" won't be rewritten by command "CONFIG REWRITE"</span>
<span class="hljs-comment"># from admin or Redis Sentinel. Since Redis always uses the last processed</span>
<span class="hljs-comment"># line as value of a configuration directive, you'd better put includes</span>
<span class="hljs-comment"># at the beginning of this file to avoid overwriting config change at runtime.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># If instead you are interested in using includes to override configuration</span>
<span class="hljs-comment"># options, it is better to use include as the last line.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># include /path/to/local.conf</span>
<span class="hljs-comment"># include /path/to/other.conf</span>
</div></code></pre>
<ol start="3">
<li>网络</li>
</ol>
<pre><code class="language-bash"><div><span class="hljs-comment">################################## NETWORK #####################################</span>

<span class="hljs-comment"># By default, if no "bind" configuration directive is specified, Redis listens</span>
<span class="hljs-comment"># for connections from all the network interfaces available on the server.</span>
<span class="hljs-comment"># It is possible to listen to just one or multiple selected interfaces using</span>
<span class="hljs-comment"># the "bind" configuration directive, followed by one or more IP addresses.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># Examples:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># bind 192.168.1.100 10.0.0.1</span>
<span class="hljs-comment"># bind 127.0.0.1 ::1</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># ``` WARNING ``` If the computer running Redis is directly exposed to the</span>
<span class="hljs-comment"># internet, binding to all the interfaces is dangerous and will expose the</span>
<span class="hljs-comment"># instance to everybody on the internet. So by default we uncomment the</span>
<span class="hljs-comment"># following bind directive, that will force Redis to listen only into</span>
<span class="hljs-comment"># the IPv4 loopback interface address (this means Redis will be able to</span>
<span class="hljs-comment"># accept connections only from clients running into the same computer it</span>
<span class="hljs-comment"># is running).</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES</span>
<span class="hljs-comment"># JUST COMMENT THE FOLLOWING LINE.</span>
<span class="hljs-comment"># ````````````````````````````````````````````````````````````````````````</span>
<span class="hljs-comment"># bind 127.0.0.1 # 绑定的ip，可以使用*让所有人访问</span>

<span class="hljs-comment"># Protected mode is a layer of security protection, in order to avoid that</span>
<span class="hljs-comment"># Redis instances left open on the internet are accessed and exploited.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># When protected mode is on and if:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># 1) The server is not binding explicitly to a set of addresses using the</span>
<span class="hljs-comment">#    "bind" directive.</span>
<span class="hljs-comment"># 2) No password is configured.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># The server only accepts connections from clients connecting from the</span>
<span class="hljs-comment"># IPv4 and IPv6 loopback addresses 127.0.0.1 and ::1, and from Unix domain</span>
<span class="hljs-comment"># sockets.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># By default protected mode is enabled. You should disable it only if</span>
<span class="hljs-comment"># you are sure you want clients from other hosts to connect to Redis</span>
<span class="hljs-comment"># even if no authentication is configured, nor a specific set of interfaces</span>
<span class="hljs-comment"># are explicitly listed using the "bind" directive.</span>
protected-mode yes <span class="hljs-comment"># 保护</span>
 
<span class="hljs-comment"># Accept connections on the specified port, default is 6379 (IANA #815344).</span>
<span class="hljs-comment"># If port 0 is specified Redis will not listen on a TCP socket.</span>
port 6379 <span class="hljs-comment"># 端口</span>

<span class="hljs-comment"># TCP listen() backlog.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># In high requests-per-second environments you need an high backlog in order</span>
<span class="hljs-comment"># to avoid slow clients connections issues. Note that the Linux kernel</span>
<span class="hljs-comment"># will silently truncate it to the value of /proc/sys/net/core/somaxconn so</span>
<span class="hljs-comment"># make sure to raise both the value of somaxconn and tcp_max_syn_backlog</span>
<span class="hljs-comment"># in order to get the desired effect.</span>
tcp-backlog 511

<span class="hljs-comment"># Unix socket.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># Specify the path for the Unix socket that will be used to listen for</span>
<span class="hljs-comment"># incoming connections. There is no default, so Redis will not listen</span>
<span class="hljs-comment"># on a unix socket when not specified.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># unixsocket /tmp/redis.sock</span>
<span class="hljs-comment"># unixsocketperm 700</span>

<span class="hljs-comment"># Close the connection after a client is idle for N seconds (0 to disable)</span>
timeout 0

<span class="hljs-comment"># TCP keepalive.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># If non-zero, use SO_KEEPALIVE to send TCP ACKs to clients in absence</span>
<span class="hljs-comment"># of communication. This is useful for two reasons:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># 1) Detect dead peers.</span>
<span class="hljs-comment"># 2) Take the connection alive from the point of view of network</span>
<span class="hljs-comment">#    equipment in the middle.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># On Linux, the specified value (in seconds) is the period used to send ACKs.</span>
<span class="hljs-comment"># Note that to close the connection the double of the time is needed.</span>
<span class="hljs-comment"># On other kernels the period depends on the kernel configuration.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># A reasonable value for this option is 300 seconds, which is the new</span>
<span class="hljs-comment"># Redis default starting with Redis 3.2.1.</span>
tcp-keepalive 300
</div></code></pre>
<ol start="4">
<li>通用</li>
</ol>
<pre><code class="language-bash"><div>
<span class="hljs-comment">################################# GENERAL #####################################</span>

<span class="hljs-comment"># By default Redis does not run as a daemon. Use 'yes' if you need it.</span>
<span class="hljs-comment"># Note that Redis will write a pid file in /var/run/redis.pid when daemonized.</span>
daemonize yes <span class="hljs-comment"># 以守护进程开启</span>

<span class="hljs-comment"># If you run Redis from upstart or systemd, Redis can interact with your</span>
<span class="hljs-comment"># supervision tree. Options:</span>
<span class="hljs-comment">#   supervised no      - no supervision interaction</span>
<span class="hljs-comment">#   supervised upstart - signal upstart by putting Redis into SIGSTOP mode</span>
<span class="hljs-comment">#   supervised systemd - signal systemd by writing READY=1 to $NOTIFY_SOCKET</span>
<span class="hljs-comment">#   supervised auto    - detect upstart or systemd method based on</span>
<span class="hljs-comment">#                        UPSTART_JOB or NOTIFY_SOCKET environment variables</span>
<span class="hljs-comment"># Note: these supervision methods only signal "process is ready."</span>
<span class="hljs-comment">#       They do not enable continuous liveness pings back to your supervisor.</span>
supervised no 

<span class="hljs-comment"># If a pid file is specified, Redis writes it where specified at startup</span>
<span class="hljs-comment"># and removes it at exit.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># When the server runs non daemonized, no pid file is created if none is</span>
<span class="hljs-comment"># specified in the configuration. When the server is daemonized, the pid file</span>
<span class="hljs-comment"># is used even if not specified, defaulting to "/var/run/redis.pid".</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># Creating a pid file is best effort: if Redis is not able to create it</span>
<span class="hljs-comment"># nothing bad happens, the server will start and run normally.</span>
pidfile /var/run/redis_6379.pid <span class="hljs-comment"># 如果以守护进程运行，指定pid文件</span>

<span class="hljs-comment"># Specify the server verbosity level.</span>
<span class="hljs-comment"># This can be one of:</span>
<span class="hljs-comment"># debug (a lot of information, useful for development/testing)</span>
<span class="hljs-comment"># verbose (many rarely useful info, but not a mess like the debug level)</span>
<span class="hljs-comment"># notice (moderately verbose, what you want in production probably)</span>
<span class="hljs-comment"># warning (only very important / critical messages are logged)</span>
loglevel notice <span class="hljs-comment">#日志级别</span>

<span class="hljs-comment"># Specify the log file name. Also the empty string can be used to force</span>
<span class="hljs-comment"># Redis to log on the standard output. Note that if you use standard</span>
<span class="hljs-comment"># output for logging but daemonize, logs will be sent to /dev/null</span>
logfile <span class="hljs-string">""</span> <span class="hljs-comment"># 日志的文件名</span>

<span class="hljs-comment"># To enable logging to the system logger, just set 'syslog-enabled' to yes,</span>
<span class="hljs-comment"># and optionally update the other syslog parameters to suit your needs.</span>
<span class="hljs-comment"># syslog-enabled no</span>

<span class="hljs-comment"># Specify the syslog identity.</span>
<span class="hljs-comment"># syslog-ident redis</span>

<span class="hljs-comment"># Specify the syslog facility. Must be USER or between LOCAL0-LOCAL7.</span>
<span class="hljs-comment"># syslog-facility local0</span>

<span class="hljs-comment"># Set the number of databases. The default database is DB 0, you can select</span>
<span class="hljs-comment"># a different one on a per-connection basis using SELECT &lt;dbid&gt; where</span>
<span class="hljs-comment"># dbid is a number between 0 and 'databases'-1</span>
databases 16 <span class="hljs-comment"># 数据库的数量</span>

<span class="hljs-comment"># By default Redis shows an ASCII art logo only when started to log to the</span>
<span class="hljs-comment"># standard output and if the standard output is a TTY. Basically this means</span>
<span class="hljs-comment"># that normally a logo is displayed only in interactive sessions.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># However it is possible to force the pre-4.0 behavior and always show a</span>
<span class="hljs-comment"># ASCII art logo in startup logs by setting the following option to yes.</span>
always-show-logo yes <span class="hljs-comment"># 是否显示logo</span>
</div></code></pre>
<ol start="5">
<li>快照, 规定的时间内持久化</li>
</ol>
<pre><code class="language-bash"><div><span class="hljs-comment">################################ SNAPSHOTTING  ################################</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># Save the DB on disk:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment">#   save &lt;seconds&gt; &lt;changes&gt;</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment">#   Will save the DB if both the given number of seconds and the given</span>
<span class="hljs-comment">#   number of write operations against the DB occurred.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment">#   In the example below the behaviour will be to save:</span>
<span class="hljs-comment">#   after 900 sec (15 min) if at least 1 key changed</span>
<span class="hljs-comment">#   after 300 sec (5 min) if at least 10 keys changed</span>
<span class="hljs-comment">#   after 60 sec if at least 10000 keys changed</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment">#   Note: you can disable saving completely by commenting out all "save" lines.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment">#   It is also possible to remove all the previously configured save</span>
<span class="hljs-comment">#   points by adding a save directive with a single empty string argument</span>
<span class="hljs-comment">#   like in the following example:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment">#   save ""</span>

save 900 1 <span class="hljs-comment"># 900秒类至少1个key进行了修改我们进行持久化</span>
save 300 10
save 60 10000

<span class="hljs-comment"># By default Redis will stop accepting writes if RDB snapshots are enabled</span>
<span class="hljs-comment"># (at least one save point) and the latest background save failed.</span>
<span class="hljs-comment"># This will make the user aware (in a hard way) that data is not persisting</span>
<span class="hljs-comment"># on disk properly, otherwise chances are that no one will notice and some</span>
<span class="hljs-comment"># disaster will happen.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># If the background saving process will start working again Redis will</span>
<span class="hljs-comment"># automatically allow writes again.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># However if you have setup your proper monitoring of the Redis server</span>
<span class="hljs-comment"># and persistence, you may want to disable this feature so that Redis will</span>
<span class="hljs-comment"># continue to work as usual even if there are problems with disk,</span>
<span class="hljs-comment"># permissions, and so forth.</span>
stop-writes-on-bgsave-error yes <span class="hljs-comment"># 持久化出错是否工作</span>

<span class="hljs-comment"># Compress string objects using LZF when dump .rdb databases?</span>
<span class="hljs-comment"># For default that's set to 'yes' as it's almost always a win.</span>
<span class="hljs-comment"># If you want to save some CPU in the saving child set it to 'no' but</span>
<span class="hljs-comment"># the dataset will likely be bigger if you have compressible values or keys.</span>
rdbcompression yes <span class="hljs-comment"># 是否压缩rdb文件，需要消耗一些cpu资源</span>

<span class="hljs-comment"># Since version 5 of RDB a CRC64 checksum is placed at the end of the file.</span>
<span class="hljs-comment"># This makes the format more resistant to corruption but there is a performance</span>
<span class="hljs-comment"># hit to pay (around 10%) when saving and loading RDB files, so you can disable it</span>
<span class="hljs-comment"># for maximum performances.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># RDB files created with checksum disabled have a checksum of zero that will</span>
<span class="hljs-comment"># tell the loading code to skip the check.</span>
rdbchecksum yes <span class="hljs-comment">#保存rdb文件的时候，进行错误校验</span>

<span class="hljs-comment"># The filename where to dump the DB</span>
dbfilename dump.rdb

<span class="hljs-comment"># Remove RDB files used by replication in instances without persistence</span>
<span class="hljs-comment"># enabled. By default this option is disabled, however there are environments</span>
<span class="hljs-comment"># where for regulations or other security concerns, RDB files persisted on</span>
<span class="hljs-comment"># disk by masters in order to feed replicas, or stored on disk by replicas</span>
<span class="hljs-comment"># in order to load them for the initial synchronization, should be deleted</span>
<span class="hljs-comment"># ASAP. Note that this option ONLY WORKS in instances that have both AOF</span>
<span class="hljs-comment"># and RDB persistence disabled, otherwise is completely ignored.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># An alternative (and sometimes better) way to obtain the same effect is</span>
<span class="hljs-comment"># to use diskless replication on both master and replicas instances. However</span>
<span class="hljs-comment"># in the case of replicas, diskless is not always an option.</span>
rdb-del-sync-files no

<span class="hljs-comment"># The working directory.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># The DB will be written inside this directory, with the filename specified</span>
<span class="hljs-comment"># above using the 'dbfilename' configuration directive.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># The Append Only File will also be created inside this directory.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># Note that you must specify a directory here, not a file name.</span>
dir ./ <span class="hljs-comment"># rdb文件保存目录</span>
</div></code></pre>
<ol start="6">
<li>复制</li>
</ol>
<pre><code class="language-bash"><div><span class="hljs-comment">################################# REPLICATION #################################</span>

<span class="hljs-comment"># Master-Replica replication. Use replicaof to make a Redis instance a copy of</span>
<span class="hljs-comment"># another Redis server. A few things to understand ASAP about Redis replication.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment">#   +------------------+      +---------------+</span>
<span class="hljs-comment">#   |      Master      | ---&gt; |    Replica    |</span>
<span class="hljs-comment">#   | (receive writes) |      |  (exact copy) |</span>
<span class="hljs-comment">#   +------------------+      +---------------+</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># 1) Redis replication is asynchronous, but you can configure a master to</span>
<span class="hljs-comment">#    stop accepting writes if it appears to be not connected with at least</span>
<span class="hljs-comment">#    a given number of replicas.</span>
<span class="hljs-comment"># 2) Redis replicas are able to perform a partial resynchronization with the</span>
<span class="hljs-comment">#    master if the replication link is lost for a relatively small amount of</span>
<span class="hljs-comment">#    time. You may want to configure the replication backlog size (see the next</span>
<span class="hljs-comment">#    sections of this file) with a sensible value depending on your needs.</span>
<span class="hljs-comment"># 3) Replication is automatic and does not need user intervention. After a</span>
<span class="hljs-comment">#    network partition replicas automatically try to reconnect to masters</span>
<span class="hljs-comment">#    and resynchronize with them.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># replicaof &lt;masterip&gt; &lt;masterport&gt;</span>

<span class="hljs-comment"># If the master is password protected (using the "requirepass" configuration</span>
<span class="hljs-comment"># directive below) it is possible to tell the replica to authenticate before</span>
<span class="hljs-comment"># starting the replication synchronization process, otherwise the master will</span>
<span class="hljs-comment"># refuse the replica request.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># masterauth &lt;master-password&gt;</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># However this is not enough if you are using Redis ACLs (for Redis version</span>
<span class="hljs-comment"># 6 or greater), and the default user is not capable of running the PSYNC</span>
<span class="hljs-comment"># command and/or other commands needed for replication. In this case it's</span>
<span class="hljs-comment"># better to configure a special user to use with replication, and specify the</span>
<span class="hljs-comment"># masteruser configuration as such:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># masteruser &lt;username&gt;</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># When masteruser is specified, the replica will authenticate against its</span>
<span class="hljs-comment"># master using the new AUTH form: AUTH &lt;username&gt; &lt;password&gt;.</span>

<span class="hljs-comment"># When a replica loses its connection with the master, or when the replication</span>
<span class="hljs-comment"># is still in progress, the replica can act in two different ways:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># 1) if replica-serve-stale-data is set to 'yes' (the default) the replica will</span>
<span class="hljs-comment">#    still reply to client requests, possibly with out of date data, or the</span>
<span class="hljs-comment">#    data set may just be empty if this is the first synchronization.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># 2) if replica-serve-stale-data is set to 'no' the replica will reply with</span>
<span class="hljs-comment">#    an error "SYNC with master in progress" to all the kind of commands</span>
<span class="hljs-comment">#    but to INFO, replicaOF, AUTH, PING, SHUTDOWN, REPLCONF, ROLE, CONFIG,</span>
<span class="hljs-comment">#    SUBSCRIBE, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, PUBLISH, PUBSUB,</span>
<span class="hljs-comment">#    COMMAND, POST, HOST: and LATENCY.</span>
<span class="hljs-comment">#</span>
replica-serve-stale-data yes

<span class="hljs-comment"># You can configure a replica instance to accept writes or not. Writing against</span>
<span class="hljs-comment"># a replica instance may be useful to store some ephemeral data (because data</span>
<span class="hljs-comment"># written on a replica will be easily deleted after resync with the master) but</span>
<span class="hljs-comment"># may also cause problems if clients are writing to it because of a</span>
<span class="hljs-comment"># misconfiguration.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># Since Redis 2.6 by default replicas are read-only.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># Note: read only replicas are not designed to be exposed to untrusted clients</span>
<span class="hljs-comment"># on the internet. It's just a protection layer against misuse of the instance.</span>
<span class="hljs-comment"># Still a read only replica exports by default all the administrative commands</span>
<span class="hljs-comment"># such as CONFIG, DEBUG, and so forth. To a limited extent you can improve</span>
<span class="hljs-comment"># security of read only replicas using 'rename-command' to shadow all the</span>
<span class="hljs-comment"># administrative / dangerous commands.</span>
replica-read-only yes

<span class="hljs-comment"># Replication SYNC strategy: disk or socket.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># New replicas and reconnecting replicas that are not able to continue the</span>
<span class="hljs-comment"># replication process just receiving differences, need to do what is called a</span>
<span class="hljs-comment"># "full synchronization". An RDB file is transmitted from the master to the</span>
<span class="hljs-comment"># replicas.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># The transmission can happen in two different ways:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># 1) Disk-backed: The Redis master creates a new process that writes the RDB</span>
<span class="hljs-comment">#                 file on disk. Later the file is transferred by the parent</span>
<span class="hljs-comment">#                 process to the replicas incrementally.</span>
<span class="hljs-comment"># 2) Diskless: The Redis master creates a new process that directly writes the</span>
<span class="hljs-comment">#              RDB file to replica sockets, without touching the disk at all.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># With disk-backed replication, while the RDB file is generated, more replicas</span>
<span class="hljs-comment"># can be queued and served with the RDB file as soon as the current child</span>
<span class="hljs-comment"># producing the RDB file finishes its work. With diskless replication instead</span>
<span class="hljs-comment"># once the transfer starts, new replicas arriving will be queued and a new</span>
<span class="hljs-comment"># transfer will start when the current one terminates.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># When diskless replication is used, the master waits a configurable amount of</span>
<span class="hljs-comment"># time (in seconds) before starting the transfer in the hope that multiple</span>
<span class="hljs-comment"># replicas will arrive and the transfer can be parallelized.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># With slow disks and fast (large bandwidth) networks, diskless replication</span>
<span class="hljs-comment"># works better.</span>
repl-diskless-sync no

<span class="hljs-comment"># When diskless replication is enabled, it is possible to configure the delay</span>
<span class="hljs-comment"># the server waits in order to spawn the child that transfers the RDB via socket</span>
<span class="hljs-comment"># to the replicas.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># This is important since once the transfer starts, it is not possible to serve</span>
<span class="hljs-comment"># new replicas arriving, that will be queued for the next RDB transfer, so the</span>
<span class="hljs-comment"># server waits a delay in order to let more replicas arrive.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># The delay is specified in seconds, and by default is 5 seconds. To disable</span>
<span class="hljs-comment"># it entirely just set it to 0 seconds and the transfer will start ASAP.</span>
repl-diskless-sync-delay 5

<span class="hljs-comment"># -----------------------------------------------------------------------------</span>
<span class="hljs-comment"># WARNING: RDB diskless load is experimental. Since in this setup the replica</span>
<span class="hljs-comment"># does not immediately store an RDB on disk, it may cause data loss during</span>
<span class="hljs-comment"># failovers. RDB diskless load + Redis modules not handling I/O reads may also</span>
<span class="hljs-comment"># cause Redis to abort in case of I/O errors during the initial synchronization</span>
<span class="hljs-comment"># stage with the master. Use only if your do what you are doing.</span>
<span class="hljs-comment"># -----------------------------------------------------------------------------</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># Replica can load the RDB it reads from the replication link directly from the</span>
<span class="hljs-comment"># socket, or store the RDB to a file and read that file after it was completely</span>
<span class="hljs-comment"># recived from the master.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># In many cases the disk is slower than the network, and storing and loading</span>
<span class="hljs-comment"># the RDB file may increase replication time (and even increase the master's</span>
<span class="hljs-comment"># Copy on Write memory and salve buffers).</span>
<span class="hljs-comment"># However, parsing the RDB file directly from the socket may mean that we have</span>
<span class="hljs-comment"># to flush the contents of the current database before the full rdb was</span>
<span class="hljs-comment"># received. For this reason we have the following options:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># "disabled"    - Don't use diskless load (store the rdb file to the disk first)</span>
<span class="hljs-comment"># "on-empty-db" - Use diskless load only when it is completely safe.</span>
<span class="hljs-comment"># "swapdb"      - Keep a copy of the current db contents in RAM while parsing</span>
<span class="hljs-comment">#                 the data directly from the socket. note that this requires</span>
<span class="hljs-comment">#                 sufficient memory, if you don't have it, you risk an OOM kill.</span>
repl-diskless-load disabled

<span class="hljs-comment"># Replicas send PINGs to server in a predefined interval. It's possible to</span>
<span class="hljs-comment"># change this interval with the repl_ping_replica_period option. The default</span>
<span class="hljs-comment"># value is 10 seconds.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># repl-ping-replica-period 10</span>

<span class="hljs-comment"># The following option sets the replication timeout for:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># 1) Bulk transfer I/O during SYNC, from the point of view of replica.</span>
<span class="hljs-comment"># 2) Master timeout from the point of view of replicas (data, pings).</span>
<span class="hljs-comment"># 3) Replica timeout from the point of view of masters (REPLCONF ACK pings).</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># It is important to make sure that this value is greater than the value</span>
<span class="hljs-comment"># specified for repl-ping-replica-period otherwise a timeout will be detected</span>
<span class="hljs-comment"># every time there is low traffic between the master and the replica.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># repl-timeout 60</span>

<span class="hljs-comment"># Disable TCP_NODELAY on the replica socket after SYNC?</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># If you select "yes" Redis will use a smaller number of TCP packets and</span>
<span class="hljs-comment"># less bandwidth to send data to replicas. But this can add a delay for</span>
<span class="hljs-comment"># the data to appear on the replica side, up to 40 milliseconds with</span>
<span class="hljs-comment"># Linux kernels using a default configuration.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># If you select "no" the delay for data to appear on the replica side will</span>
<span class="hljs-comment"># be reduced but more bandwidth will be used for replication.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># By default we optimize for low latency, but in very high traffic conditions</span>
<span class="hljs-comment"># or when the master and replicas are many hops away, turning this to "yes" may</span>
<span class="hljs-comment"># be a good idea.</span>
repl-disable-tcp-nodelay no

<span class="hljs-comment"># Set the replication backlog size. The backlog is a buffer that accumulates</span>
<span class="hljs-comment"># replica data when replicas are disconnected for some time, so that when a</span>
<span class="hljs-comment"># replica wants to reconnect again, often a full resync is not needed, but a</span>
<span class="hljs-comment"># partial resync is enough, just passing the portion of data the replica</span>
<span class="hljs-comment"># missed while disconnected.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># The bigger the replication backlog, the longer the time the replica can be</span>
<span class="hljs-comment"># disconnected and later be able to perform a partial resynchronization.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># The backlog is only allocated once there is at least a replica connected.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># repl-backlog-size 1mb</span>

<span class="hljs-comment"># After a master has no longer connected replicas for some time, the backlog</span>
<span class="hljs-comment"># will be freed. The following option configures the amount of seconds that</span>
<span class="hljs-comment"># need to elapse, starting from the time the last replica disconnected, for</span>
<span class="hljs-comment"># the backlog buffer to be freed.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># Note that replicas never free the backlog for timeout, since they may be</span>
<span class="hljs-comment"># promoted to masters later, and should be able to correctly "partially</span>
<span class="hljs-comment"># resynchronize" with the replicas: hence they should always accumulate backlog.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># A value of 0 means to never release the backlog.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># repl-backlog-ttl 3600</span>

<span class="hljs-comment"># The replica priority is an integer number published by Redis in the INFO</span>
<span class="hljs-comment"># output. It is used by Redis Sentinel in order to select a replica to promote</span>
<span class="hljs-comment"># into a master if the master is no longer working correctly.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># A replica with a low priority number is considered better for promotion, so</span>
<span class="hljs-comment"># for instance if there are three replicas with priority 10, 100, 25 Sentinel</span>
<span class="hljs-comment"># will pick the one with priority 10, that is the lowest.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># However a special priority of 0 marks the replica as not able to perform the</span>
<span class="hljs-comment"># role of master, so a replica with priority of 0 will never be selected by</span>
<span class="hljs-comment"># Redis Sentinel for promotion.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># By default the priority is 100.</span>
replica-priority 100

<span class="hljs-comment"># It is possible for a master to stop accepting writes if there are less than</span>
<span class="hljs-comment"># N replicas connected, having a lag less or equal than M seconds.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># The N replicas need to be in "online" state.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># The lag in seconds, that must be &lt;= the specified value, is calculated from</span>
<span class="hljs-comment"># the last ping received from the replica, that is usually sent every second.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># This option does not GUARANTEE that N replicas will accept the write, but</span>
<span class="hljs-comment"># will limit the window of exposure for lost writes in case not enough replicas</span>
<span class="hljs-comment"># are available, to the specified number of seconds.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># For example to require at least 3 replicas with a lag &lt;= 10 seconds use:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># min-replicas-to-write 3</span>
<span class="hljs-comment"># min-replicas-max-lag 10</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># Setting one or the other to 0 disables the feature.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># By default min-replicas-to-write is set to 0 (feature disabled) and</span>
<span class="hljs-comment"># min-replicas-max-lag is set to 10.</span>

<span class="hljs-comment"># A Redis master is able to list the address and port of the attached</span>
<span class="hljs-comment"># replicas in different ways. For example the "INFO replication" section</span>
<span class="hljs-comment"># offers this information, which is used, among other tools, by</span>
<span class="hljs-comment"># Redis Sentinel in order to discover replica instances.</span>
<span class="hljs-comment"># Another place where this info is available is in the output of the</span>
<span class="hljs-comment"># "ROLE" command of a master.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># The listed IP and address normally reported by a replica is obtained</span>
<span class="hljs-comment"># in the following way:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment">#   IP: The address is auto detected by checking the peer address</span>
<span class="hljs-comment">#   of the socket used by the replica to connect with the master.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment">#   Port: The port is communicated by the replica during the replication</span>
<span class="hljs-comment">#   handshake, and is normally the port that the replica is using to</span>
<span class="hljs-comment">#   listen for connections.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># However when port forwarding or Network Address Translation (NAT) is</span>
<span class="hljs-comment"># used, the replica may be actually reachable via different IP and port</span>
<span class="hljs-comment"># pairs. The following two options can be used by a replica in order to</span>
<span class="hljs-comment"># report to its master a specific set of IP and port, so that both INFO</span>
<span class="hljs-comment"># and ROLE will report those values.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># There is no need to use both the options if you need to override just</span>
<span class="hljs-comment"># the port or the IP address.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># replica-announce-ip 5.5.5.5</span>
<span class="hljs-comment"># replica-announce-port 1234</span>

<span class="hljs-comment">############################### KEYS TRACKING #################################</span>

<span class="hljs-comment"># Redis implements server assisted support for client side caching of values.</span>
<span class="hljs-comment"># This is implemented using an invalidation table that remembers, using</span>
<span class="hljs-comment"># 16 millions of slots, what clients may have certain subsets of keys. In turn</span>
<span class="hljs-comment"># this is used in order to send invalidation messages to clients. Please</span>
<span class="hljs-comment"># to understand more about the feature check this page:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment">#   https://redis.io/topics/client-side-caching</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># When tracking is enabled for a client, all the read only queries are assumed</span>
<span class="hljs-comment"># to be cached: this will force Redis to store information in the invalidation</span>
<span class="hljs-comment"># table. When keys are modified, such information is flushed away, and</span>
<span class="hljs-comment"># invalidation messages are sent to the clients. However if the workload is</span>
<span class="hljs-comment"># heavily dominated by reads, Redis could use more and more memory in order</span>
<span class="hljs-comment"># to track the keys fetched by many clients.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># For this reason it is possible to configure a maximum fill value for the</span>
<span class="hljs-comment"># invalidation table. By default it is set to 1M of keys, and once this limit</span>
<span class="hljs-comment"># is reached, Redis will start to evict keys in the invalidation table</span>
<span class="hljs-comment"># even if they were not modified, just to reclaim memory: this will in turn</span>
<span class="hljs-comment"># force the clients to invalidate the cached values. Basically the table</span>
<span class="hljs-comment"># maximum size is a trade off between the memory you want to spend server</span>
<span class="hljs-comment"># side to track information about who cached what, and the ability of clients</span>
<span class="hljs-comment"># to retain cached objects in memory.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># If you set the value to 0, it means there are no limits, and Redis will</span>
<span class="hljs-comment"># retain as many keys as needed in the invalidation table.</span>
<span class="hljs-comment"># In the "stats" INFO section, you can find information about the number of</span>
<span class="hljs-comment"># keys in the invalidation table at every given moment.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># Note: when key tracking is used in broadcasting mode, no memory is used</span>
<span class="hljs-comment"># in the server side so this setting is useless.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># tracking-table-max-keys 1000000</span>

<span class="hljs-comment">################################## SECURITY ###################################</span>

<span class="hljs-comment"># Warning: since Redis is pretty fast an outside user can try up to</span>
<span class="hljs-comment"># 1 million passwords per second against a modern box. This means that you</span>
<span class="hljs-comment"># should use very strong passwords, otherwise they will be very easy to break.</span>
<span class="hljs-comment"># Note that because the password is really a shared secret between the client</span>
<span class="hljs-comment"># and the server, and should not be memorized by any human, the password</span>
<span class="hljs-comment"># can be easily a long string from /dev/urandom or whatever, so by using a</span>
<span class="hljs-comment"># long and unguessable password no brute force attack will be possible.</span>

<span class="hljs-comment"># Redis ACL users are defined in the following format:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment">#   user &lt;username&gt; ... acl rules ...</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># For example:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment">#   user worker +@list +@connection `jobs:* on &gt;ffa9203c493aa99</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># The special username "default" is used for new connections. If this user</span>
<span class="hljs-comment"># has the "nopass" rule, then new connections will be immediately authenticated</span>
<span class="hljs-comment"># as the "default" user without the need of any password provided via the</span>
<span class="hljs-comment"># AUTH command. Otherwise if the "default" user is not flagged with "nopass"</span>
<span class="hljs-comment"># the connections will start in not authenticated state, and will require</span>
<span class="hljs-comment"># AUTH (or the HELLO command AUTH option) in order to be authenticated and</span>
<span class="hljs-comment"># start to work.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># The ACL rules that describe what an user can do are the following:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment">#  on           Enable the user: it is possible to authenticate as this user.</span>
<span class="hljs-comment">#  off          Disable the user: it's no longer possible to authenticate</span>
<span class="hljs-comment">#               with this user, however the already authenticated connections</span>
<span class="hljs-comment">#               will still work.</span>
<span class="hljs-comment">#  +&lt;command&gt;   Allow the execution of that command</span>
<span class="hljs-comment">#  -&lt;command&gt;   Disallow the execution of that command</span>
<span class="hljs-comment">#  +@&lt;category&gt; Allow the execution of all the commands in such category</span>
<span class="hljs-comment">#               with valid categories are like @admin, @set, @sortedset, ...</span>
<span class="hljs-comment">#               and so forth, see the full list in the server.c file where</span>
<span class="hljs-comment">#               the Redis command table is described and defined.</span>
<span class="hljs-comment">#               The special category @all means all the commands, but currently</span>
<span class="hljs-comment">#               present in the server, and that will be loaded in the future</span>
<span class="hljs-comment">#               via modules.</span>
<span class="hljs-comment">#  +&lt;command&gt;|subcommand    Allow a specific subcommand of an otherwise</span>
<span class="hljs-comment">#                           disabled command. Note that this form is not</span>
<span class="hljs-comment">#                           allowed as negative like -DEBUG|SEGFAULT, but</span>
<span class="hljs-comment">#                           only additive starting with "+".</span>
<span class="hljs-comment">#  allcommands  Alias for +@all. Note that it implies the ability to execute</span>
<span class="hljs-comment">#               all the future commands loaded via the modules system.</span>
<span class="hljs-comment">#  nocommands   Alias for -@all.</span>
<span class="hljs-comment">#  `&lt;pattern&gt;   Add a pattern of keys that can be mentioned as part of</span>
<span class="hljs-comment">#               commands. For instance `* allows all the keys. The pattern</span>
<span class="hljs-comment">#               is a glob-style pattern like the one of KEYS.</span>
<span class="hljs-comment">#               It is possible to specify multiple patterns.</span>
<span class="hljs-comment">#  allkeys      Alias for `*</span>
<span class="hljs-comment">#  resetkeys    Flush the list of allowed keys patterns.</span>
<span class="hljs-comment">#  &gt;&lt;password&gt;  Add this passowrd to the list of valid password for the user.</span>
<span class="hljs-comment">#               For example &gt;mypass will add "mypass" to the list.</span>
<span class="hljs-comment">#               This directive clears the "nopass" flag (see later).</span>
<span class="hljs-comment">#  &lt;&lt;password&gt;  Remove this password from the list of valid passwords.</span>
<span class="hljs-comment">#  nopass       All the set passwords of the user are removed, and the user</span>
<span class="hljs-comment">#               is flagged as requiring no password: it means that every</span>
<span class="hljs-comment">#               password will work against this user. If this directive is</span>
<span class="hljs-comment">#               used for the default user, every new connection will be</span>
<span class="hljs-comment">#               immediately authenticated with the default user without</span>
<span class="hljs-comment">#               any explicit AUTH command required. Note that the "resetpass"</span>
<span class="hljs-comment">#               directive will clear this condition.</span>
<span class="hljs-comment">#  resetpass    Flush the list of allowed passwords. Moreover removes the</span>
<span class="hljs-comment">#               "nopass" status. After "resetpass" the user has no associated</span>
<span class="hljs-comment">#               passwords and there is no way to authenticate without adding</span>
<span class="hljs-comment">#               some password (or setting it as "nopass" later).</span>
<span class="hljs-comment">#  reset        Performs the following actions: resetpass, resetkeys, off,</span>
<span class="hljs-comment">#               -@all. The user returns to the same state it has immediately</span>
<span class="hljs-comment">#               after its creation.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># ACL rules can be specified in any order: for instance you can start with</span>
<span class="hljs-comment"># passwords, then flags, or key patterns. However note that the additive</span>
<span class="hljs-comment"># and subtractive rules will CHANGE MEANING depending on the ordering.</span>
<span class="hljs-comment"># For instance see the following example:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment">#   user alice on +@all -DEBUG `* &gt;somepassword</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># This will allow "alice" to use all the commands with the exception of the</span>
<span class="hljs-comment"># DEBUG command, since +@all added all the commands to the set of the commands</span>
<span class="hljs-comment"># alice can use, and later DEBUG was removed. However if we invert the order</span>
<span class="hljs-comment"># of two ACL rules the result will be different:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment">#   user alice on -DEBUG +@all `* &gt;somepassword</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># Now DEBUG was removed when alice had yet no commands in the set of allowed</span>
<span class="hljs-comment"># commands, later all the commands are added, so the user will be able to</span>
<span class="hljs-comment"># execute everything.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># Basically ACL rules are processed left-to-right.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># For more information about ACL configuration please refer to</span>
<span class="hljs-comment"># the Redis web site at https://redis.io/topics/acl</span>

<span class="hljs-comment"># ACL LOG</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># The ACL Log tracks failed commands and authentication events associated</span>
<span class="hljs-comment"># with ACLs. The ACL Log is useful to troubleshoot failed commands blocked </span>
<span class="hljs-comment"># by ACLs. The ACL Log is stored in and consumes memory. There is no limit</span>
<span class="hljs-comment"># to its length.You can reclaim memory with ACL LOG RESET or set a maximum</span>
<span class="hljs-comment"># length below.</span>
acllog-max-len 128

<span class="hljs-comment"># Using an external ACL file</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># Instead of configuring users here in this file, it is possible to use</span>
<span class="hljs-comment"># a stand-alone file just listing users. The two methods cannot be mixed:</span>
<span class="hljs-comment"># if you configure users here and at the same time you activate the exteranl</span>
<span class="hljs-comment"># ACL file, the server will refuse to start.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># The format of the external ACL user file is exactly the same as the</span>
<span class="hljs-comment"># format that is used inside redis.conf to describe users.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># aclfile /etc/redis/users.acl</span>

<span class="hljs-comment"># IMPORTANT <span class="hljs-doctag">NOTE:</span> starting with Redis 6 "requirepass" is just a compatiblity</span>
<span class="hljs-comment"># layer on top of the new ACL system. The option effect will be just setting</span>
<span class="hljs-comment"># the password for the default user. Clients will still authenticate using</span>
<span class="hljs-comment"># AUTH &lt;password&gt; as usually, or more explicitly with AUTH default &lt;password&gt;</span>
<span class="hljs-comment"># if they follow the new protocol: both will work.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># requirepass foobared</span>

<span class="hljs-comment"># Command renaming (DEPRECATED).</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># ------------------------------------------------------------------------</span>
<span class="hljs-comment"># WARNING: avoid using this option if possible. Instead use ACLs to remove</span>
<span class="hljs-comment"># commands from the default user, and put them only in some admin user you</span>
<span class="hljs-comment"># create for administrative purposes.</span>
<span class="hljs-comment"># ------------------------------------------------------------------------</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># It is possible to change the name of dangerous commands in a shared</span>
<span class="hljs-comment"># environment. For instance the CONFIG command may be renamed into something</span>
<span class="hljs-comment"># hard to guess so that it will still be available for internal-use tools</span>
<span class="hljs-comment"># but not available for general clients.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># Example:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># It is also possible to completely kill a command by renaming it into</span>
<span class="hljs-comment"># an empty string:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># rename-command CONFIG ""</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># Please note that changing the name of commands that are logged into the</span>
<span class="hljs-comment"># AOF file or transmitted to replicas may cause problems.</span>

<span class="hljs-comment">################################### CLIENTS ####################################</span>

<span class="hljs-comment"># Set the max number of connected clients at the same time. By default</span>
<span class="hljs-comment"># this limit is set to 10000 clients, however if the Redis server is not</span>
<span class="hljs-comment"># able to configure the process file limit to allow for the specified limit</span>
<span class="hljs-comment"># the max number of allowed clients is set to the current file limit</span>
<span class="hljs-comment"># minus 32 (as Redis reserves a few file descriptors for internal uses).</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># Once the limit is reached Redis will close all the new connections sending</span>
<span class="hljs-comment"># an error 'max number of clients reached'.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># maxclients 10000</span>
</div></code></pre>
<ol start="8">
<li>安全, 通过config set requirepass &quot;密码&quot;，设置密码, 使用密码进行登录 auth 密码</li>
</ol>
<pre><code class="language-bash"><div><span class="hljs-comment">################################## SECURITY ###################################</span>

<span class="hljs-comment"># Warning: since Redis is pretty fast an outside user can try up to</span>
<span class="hljs-comment"># 1 million passwords per second against a modern box. This means that you</span>
<span class="hljs-comment"># should use very strong passwords, otherwise they will be very easy to break.</span>
<span class="hljs-comment"># Note that because the password is really a shared secret between the client</span>
<span class="hljs-comment"># and the server, and should not be memorized by any human, the password</span>
<span class="hljs-comment"># can be easily a long string from /dev/urandom or whatever, so by using a</span>
<span class="hljs-comment"># long and unguessable password no brute force attack will be possible.</span>

<span class="hljs-comment"># Redis ACL users are defined in the following format:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment">#   user &lt;username&gt; ... acl rules ...</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># For example:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment">#   user worker +@list +@connection `jobs:* on &gt;ffa9203c493aa99</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># The special username "default" is used for new connections. If this user</span>
<span class="hljs-comment"># has the "nopass" rule, then new connections will be immediately authenticated</span>
<span class="hljs-comment"># as the "default" user without the need of any password provided via the</span>
<span class="hljs-comment"># AUTH command. Otherwise if the "default" user is not flagged with "nopass"</span>
<span class="hljs-comment"># the connections will start in not authenticated state, and will require</span>
<span class="hljs-comment"># AUTH (or the HELLO command AUTH option) in order to be authenticated and</span>
<span class="hljs-comment"># start to work.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># The ACL rules that describe what an user can do are the following:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment">#  on           Enable the user: it is possible to authenticate as this user.</span>
<span class="hljs-comment">#  off          Disable the user: it's no longer possible to authenticate</span>
<span class="hljs-comment">#               with this user, however the already authenticated connections</span>
<span class="hljs-comment">#               will still work.</span>
<span class="hljs-comment">#  +&lt;command&gt;   Allow the execution of that command</span>
<span class="hljs-comment">#  -&lt;command&gt;   Disallow the execution of that command</span>
<span class="hljs-comment">#  +@&lt;category&gt; Allow the execution of all the commands in such category</span>
<span class="hljs-comment">#               with valid categories are like @admin, @set, @sortedset, ...</span>
<span class="hljs-comment">#               and so forth, see the full list in the server.c file where</span>
<span class="hljs-comment">#               the Redis command table is described and defined.</span>
<span class="hljs-comment">#               The special category @all means all the commands, but currently</span>
<span class="hljs-comment">#               present in the server, and that will be loaded in the future</span>
<span class="hljs-comment">#               via modules.</span>
<span class="hljs-comment">#  +&lt;command&gt;|subcommand    Allow a specific subcommand of an otherwise</span>
<span class="hljs-comment">#                           disabled command. Note that this form is not</span>
<span class="hljs-comment">#                           allowed as negative like -DEBUG|SEGFAULT, but</span>
<span class="hljs-comment">#                           only additive starting with "+".</span>
<span class="hljs-comment">#  allcommands  Alias for +@all. Note that it implies the ability to execute</span>
<span class="hljs-comment">#               all the future commands loaded via the modules system.</span>
<span class="hljs-comment">#  nocommands   Alias for -@all.</span>
<span class="hljs-comment">#  `&lt;pattern&gt;   Add a pattern of keys that can be mentioned as part of</span>
<span class="hljs-comment">#               commands. For instance `* allows all the keys. The pattern</span>
<span class="hljs-comment">#               is a glob-style pattern like the one of KEYS.</span>
<span class="hljs-comment">#               It is possible to specify multiple patterns.</span>
<span class="hljs-comment">#  allkeys      Alias for `*</span>
<span class="hljs-comment">#  resetkeys    Flush the list of allowed keys patterns.</span>
<span class="hljs-comment">#  &gt;&lt;password&gt;  Add this passowrd to the list of valid password for the user.</span>
<span class="hljs-comment">#               For example &gt;mypass will add "mypass" to the list.</span>
<span class="hljs-comment">#               This directive clears the "nopass" flag (see later).</span>
<span class="hljs-comment">#  &lt;&lt;password&gt;  Remove this password from the list of valid passwords.</span>
<span class="hljs-comment">#  nopass       All the set passwords of the user are removed, and the user</span>
<span class="hljs-comment">#               is flagged as requiring no password: it means that every</span>
<span class="hljs-comment">#               password will work against this user. If this directive is</span>
<span class="hljs-comment">#               used for the default user, every new connection will be</span>
<span class="hljs-comment">#               immediately authenticated with the default user without</span>
<span class="hljs-comment">#               any explicit AUTH command required. Note that the "resetpass"</span>
<span class="hljs-comment">#               directive will clear this condition.</span>
<span class="hljs-comment">#  resetpass    Flush the list of allowed passwords. Moreover removes the</span>
<span class="hljs-comment">#               "nopass" status. After "resetpass" the user has no associated</span>
<span class="hljs-comment">#               passwords and there is no way to authenticate without adding</span>
<span class="hljs-comment">#               some password (or setting it as "nopass" later).</span>
<span class="hljs-comment">#  reset        Performs the following actions: resetpass, resetkeys, off,</span>
<span class="hljs-comment">#               -@all. The user returns to the same state it has immediately</span>
<span class="hljs-comment">#               after its creation.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># ACL rules can be specified in any order: for instance you can start with</span>
<span class="hljs-comment"># passwords, then flags, or key patterns. However note that the additive</span>
<span class="hljs-comment"># and subtractive rules will CHANGE MEANING depending on the ordering.</span>
<span class="hljs-comment"># For instance see the following example:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment">#   user alice on +@all -DEBUG `* &gt;somepassword</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># This will allow "alice" to use all the commands with the exception of the</span>
<span class="hljs-comment"># DEBUG command, since +@all added all the commands to the set of the commands</span>
<span class="hljs-comment"># alice can use, and later DEBUG was removed. However if we invert the order</span>
<span class="hljs-comment"># of two ACL rules the result will be different:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment">#   user alice on -DEBUG +@all `* &gt;somepassword</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># Now DEBUG was removed when alice had yet no commands in the set of allowed</span>
<span class="hljs-comment"># commands, later all the commands are added, so the user will be able to</span>
<span class="hljs-comment"># execute everything.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># Basically ACL rules are processed left-to-right.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># For more information about ACL configuration please refer to</span>
<span class="hljs-comment"># the Redis web site at https://redis.io/topics/acl</span>

<span class="hljs-comment"># ACL LOG</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># The ACL Log tracks failed commands and authentication events associated</span>
<span class="hljs-comment"># with ACLs. The ACL Log is useful to troubleshoot failed commands blocked </span>
<span class="hljs-comment"># by ACLs. The ACL Log is stored in and consumes memory. There is no limit</span>
<span class="hljs-comment"># to its length.You can reclaim memory with ACL LOG RESET or set a maximum</span>
<span class="hljs-comment"># length below.</span>
acllog-max-len 128

<span class="hljs-comment"># Using an external ACL file</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># Instead of configuring users here in this file, it is possible to use</span>
<span class="hljs-comment"># a stand-alone file just listing users. The two methods cannot be mixed:</span>
<span class="hljs-comment"># if you configure users here and at the same time you activate the exteranl</span>
<span class="hljs-comment"># ACL file, the server will refuse to start.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># The format of the external ACL user file is exactly the same as the</span>
<span class="hljs-comment"># format that is used inside redis.conf to describe users.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># aclfile /etc/redis/users.acl</span>

<span class="hljs-comment"># IMPORTANT <span class="hljs-doctag">NOTE:</span> starting with Redis 6 "requirepass" is just a compatiblity</span>
<span class="hljs-comment"># layer on top of the new ACL system. The option effect will be just setting</span>
<span class="hljs-comment"># the password for the default user. Clients will still authenticate using</span>
<span class="hljs-comment"># AUTH &lt;password&gt; as usually, or more explicitly with AUTH default &lt;password&gt;</span>
<span class="hljs-comment"># if they follow the new protocol: both will work.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># requirepass foobared</span>

<span class="hljs-comment"># Command renaming (DEPRECATED).</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># ------------------------------------------------------------------------</span>
<span class="hljs-comment"># WARNING: avoid using this option if possible. Instead use ACLs to remove</span>
<span class="hljs-comment"># commands from the default user, and put them only in some admin user you</span>
<span class="hljs-comment"># create for administrative purposes.</span>
<span class="hljs-comment"># ------------------------------------------------------------------------</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># It is possible to change the name of dangerous commands in a shared</span>
<span class="hljs-comment"># environment. For instance the CONFIG command may be renamed into something</span>
<span class="hljs-comment"># hard to guess so that it will still be available for internal-use tools</span>
<span class="hljs-comment"># but not available for general clients.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># Example:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># It is also possible to completely kill a command by renaming it into</span>
<span class="hljs-comment"># an empty string:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># rename-command CONFIG ""</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># Please note that changing the name of commands that are logged into the</span>
<span class="hljs-comment"># AOF file or transmitted to replicas may cause problems.</span>
</div></code></pre>

    </body>
    </html>